Tag: 同步

如何使用Java同步共享文件夹中的文件访问(或者:网络级别的ReadWriteLock)

我在一个虚拟机中运行多个应用程序。 我在一台服务器上运行多个虚拟机。 我有多台服务器。 它们都使用linux上的共享文件夹共享文件。 所有应用程序都会读取和写入该文件。 在写入过程中,不允许任何应用程序读取此文件。 写入相同:如果应用程序正在读取文件,则不允许应用程序写入它。 如何设置同步应用程序,以便它们在读取之前等待写入过程完成,反之亦然? (必须同步vm中的应用程序以及跨服务器的应用程序) Curent实现使用“文件信号量”。 如果要写入文件,应用程序会尝试通过在共享文件夹中创建一个附加文件(将其命名为“file.semaphore”)来“获取”信号量。 如果“file.semaphore”文件已存在,则表示信号量已被其他应用程序锁定。 这种方法的问题是我无法确保“文件存在”-test和“create file” – 操作是primefaces执行的。 这样,两个应用程序可能会测试“file.semaphore”文件,看它不存在并尝试同时创建该文件。

ExecutorService.submit(Runnable task,T result)中的’result’是什么做的?

看看javadocs,它只是说 Future submit(Runnable task, T result) 提交Runnable任务以执行并返回表示该任务的Future。 Future的get方法将在成功完成后返回给定的结果。 参数: 任务 – 要提交的任务 结果 – 返回的结果 但它对结果有什么作用? 它存储了什么吗? 它只是使用结果类型来指定Future的类型吗?

确定哪个线程拥有监视器

对于Java对象,有没有办法告诉哪个Thread(或null)当前拥有其监视器? 或者至少一种方法来判断当前线程是否拥有它?

使用volatile和synchronized时,刷新或发布到各种线程的内存范围是多少?

这个问题仅涉及内存可见性,不会发生在之前和发生之后。 Java中有四种方法可以保证一个线程中的内存更改对另一个线程可见。 (参考http://gee.cs.oswego.edu/dl/cpj/jmm.html ) 写入线程释放同步锁,读取线程随后获取相同的同步锁。 如果一个字段被声明为volatile,则在写入器线程执行任何进一步的内存操作之前,写入其中的任何值都会被写入器线程刷新并使其可见(即,出于手头的目的,它立即被刷新)。 线程第一次访问对象的字段时,它会看到字段的初始值或自某个其他线程写入的值。 当一个线程终止时,所有写入的变量都被刷新到主存储器。 根据Java Concurrency in Practice,关于这些问题的圣经: volatile变量的可见性效果超出了volatile变量本身的值。 当线程A写入易失性变量并且随后线程B读取相同的变量时,在读取volatile变量之后,在写入易失性变量之前A可见的所有变量的值变为可见。 挥发性的问题 这是否意味着JVM实际上跟踪了易失性变量读写,以便知道如何将内存从A刷新到B而不是A到C ? 所以A写入变量,后来C从变量读取,然后B从变量读取,刷新是在A和B以及A和C之间的每个线程基础上完成的,而不是 B和C ? 或者,它是否暗示所有缓存的内存都被刷新,无论线程如何? 只是刷新了volatile变量,还是所有缓存的内存? 同步问题 对于synchronized关键字刷新,它表示只有锁内部更新的内存才能保证发布到其他线程。 这意味着在下面的代码中,两个运行method()线程,保留synchronized块会将staticVar2刷新到另一个线程,但不是 staticVar1 ,这是正确的吗? 此外,在method2() ,如果另一个线程正在执行method()则可以导致在发生问题之前发生 – 遇到问题。 但是,问题在于可见性。 如果线程A执行method ,那么后来的线程B执行method2() ,是从A到B发布的staticVar2的值,即使这两个线程没有通过同一个锁同步? static int staticVar1, staticVar2; void method() { staticVar1++; synchronized (lock) { staticVar2++; } } void method2() { synchronized (differentLock) { […]

如何在Java servlet中同步文件访问?

我为一个简单的目的创建了一个小型Java servlet:一旦调用它,它将执行以下步骤: 从本地文件系统读取文件foo.json 处理文件中的数据并对其进行一些更改 将更改写回文件 简化版代码: @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { FileInputStream inputStream = new FileInputStream(“foo.json”); String filecontent = IOUtils.toString(inputStream); inputStream.close(); JSONObject json = new JSONObject(filecontent); doSomeChangesTo(json); FileWriter writer = new FileWriter(“foo.json”); writer.write(json.toJSONString()); writer.flush(); writer.close(); } 现在我面临的问题是,可能会发生几乎同时通过两个或多个对servlet的http请求调用servlet。 为了避免对同一文件进行多次并行写访问,我需要以某种方式同步它。 根据我对servlet生命周期过程的理解,每个请求都会生成一个新线程,因此使用FileLock可能没有任何影响: 文件锁代表整个Java虚拟机。 它们不适合控制同一虚拟机中多个线程对文件的访问。 (来自http://docs.oracle.com/javase/7/docs/api/java/nio/channels/FileLock.html ) 我想使用synchronized(){}关键字也不起作用,因为我想同步文件系统访问而不是访问变量/对象。 那么,当该servlet上发生多个并行请求时,如何在我的servlet中同步文件系统访问?

同步function如何在java中运行?

自从我开始用Java编程以来,我一直在想这个(大约一年或两年)。 在C中,我们必须知道正确避免线程之间死锁的不同方法,因此在同步方法之间有更多的选择。 那Java呢? 当我们同步时,它如何避免将线程置于死锁状态? 它在内部如何运作? 死锁是否被避免,因为我们在更高级别上比在C(或C ++)中同步? 有关java中的死锁和同步的任何文档?

原始getter / setter方法需要java synchronized关键字?

我读了一些java代码,发现了这些函数: synchronized void setConnected(boolean connected){ this.connected = connected; } synchronized boolean isConnected(){ return connected; } 我想知道同步在这里是否有意义,或者只是作者不理解synchronized关键字的需要? 我想在这里同步是没用的。 还是我弄错了?

同步的Vs信号量

在阅读Java中的并发性时,我有以下疑虑: Java是否提供较低级别的构造然后同步以进行同步? 在什么情况下我们会使用信号量而不是synchronized(它在Java中提供监视器行为)

如何区分等待(长时间超时)退出通知或超时?

有这个等待声明: public final native void wait(long timeout) throws InterruptedException; 它可以通过InterruptedException或超时退出,或者因为在另一个线程中调用Notify / NotifyAll方法,Exception很容易捕获但是…… 有什么方法可以知道退出原因是超时还是通知? 编辑: 这是一个可行的棘手方式,(虽然我不喜欢它) long tBefore=System.currentTimeMillis(); wait(TIMEOUT); if ((System.currentTimeMillis() – tBefore) > TIMEOUT) { //timeout }

在什么情况下,空的同步块可以实现正确的线程语义?

我正在浏览一个关于我的代码库的Findbugs报告,其中一个触发的模式是一个空的synchronzied块(即synchronized (var) {} )。 文件说 : 与大多数人认识到的相比,空的同步块更加微妙且难以正确使用,并且空的同步块几乎不是比较少设计的解决方案更好的解决方案。 在我的情况下,它发生是因为块的内容已被注释掉,但synchronized语句仍然存在。 在什么情况下,空的synchronized块可以实现正确的线程语义?