使用volatile来确保Java中共享(但不是并发)数据的可见性
我正在尝试实现LZ77的快速版本,我有一个问题要问你关于并发编程的问题.
现在我有一个最终的byte []缓冲区和一个最终的int [] resultHolder,它们都有相同的长度.该计划执行以下操作: >主线程写入所有缓冲区,然后通知线程并等待它们完成. manager(主线程)中的重要事项声明如下: final byte[] buffer = new byte[SIZE]; final MemoryHelper memoryHelper = new MemoryHelper(); final ArrayBlockingQueue<Object> waitBuffer = new ArrayBlockingQueue<Object>(TOT_WORKERS); final ArrayBlockingQueue<Object> waitResult = new ArrayBlockingQueue<Object>(TOT_WORKERS); final int[] resultHolder = new int[SIZE]; MemoryHelper只是包装一个volatile字段并提供两种方法:一种用于读取它,另一种用于写入它. Worker的run()代码: public void run() { try { // Wait main thread while(manager.waitBuffer.take() != SHUTDOWN){ // Load new buffer values manager.memoryHelper.readVolatile(); // Do something for (int i = a; i <= b; i++){ manager.resultHolder[i] = manager.buffer[i] + 10; } // Flush new values of resultHolder manager.memoryHelper.writeVolatile(); // Signal job done manager.waitResult.add(Object.class); } } catch (InterruptedException e) { } } 最后,主线程的重要部分: for(int i=0; i < 100_000; i++){ // Start workers for (int j = 0; j < TOT_WORKERS; j++) waitBuffer.add(Object.class); // Wait workers for (int j = 0; j < TOT_WORKERS; j++) waitResult.take(); // Load results memoryHelper.readVolatile(); // Do something processResult(); setBuffer(); // Store buffer memoryHelper.writeVolatile(); } ArrayBlockingQueue上的同步效果很好.我怀疑是使用readVolatile()和writeVolatile().我被告知写入一个volatile字段会刷新所有以前更改的数据,然后从另一个线程读取它会使它们可见. 那么在这种情况下是否足以确保正确的可见性?从来没有真正的并发访问相同的内存区域,因此volatile字段应该比ReadWriteLock便宜很多. 解决方法
你甚至不需要volatile,因为
BlockingQueue s已经提供了必要的内存可见性保证:
通常,如果您已经进行了某种同步,则可能不需要执行任何特殊操作来确保内存可见性,因为它已经由您使用的同步原语保证. 但是,当您没有显式同步时(例如,在无锁算法中),可以使用易失性读取和写入来确保内存可见性. P. S. 此外,您似乎可以使用 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |