我看到它的方式,生产者和消费者线程都可以单独缓存计数并因此做出错误的决定。如果变量不是volatile,count ++可能只是更新缓存吗?
class Buffer {
private char [] buffer;
private int count = 0, in = 0, out = 0;
Buffer(int size)
{
buffer = new char[size];
}
public synchronized void Put(char c) {
while(count == buffer.length)
{
try { wait(); }
catch (InterruptedException e) { }
finally { }
}
System.out.println("Producing " + c + " ...");
buffer[in] = c;
in = (in + 1) % buffer.length;
count++;
notify();
}
public synchronized char Get() {
while (count == 0)
{
try { wait(); }
catch (InterruptedException e) { }
finally { }
}
char c = buffer[out];
out = (out + 1) % buffer.length;
count--;
System.out.println("Consuming " + c + " ...");
notify();
return c;
}
}
答案 0 :(得分:5)
不,两种方法都使用class AgentLoader {
public static void main(String[] args) {
String processId = ...
File agentJar = ...
ByteBuddyAgent.attach(processId, agentJar);
}
}
关键字定义,这意味着它们永远不会同时执行,并且内存将被同步。 synchronized
块内访问的变量永远不需要volatile
。
如果我们使用Java提供的其他同步机制,例如synchronized
而不是ReentrantReadWriteLock
,我们也不需要synchronized
,因为正确使用的锁具有相同的内存保证(发生) - 使用官方语言之前的关系。)
Memory Consistency Properties
"发布之前的行动"同步方法,如Lock.unlock,Semaphore.release和CountDownLatch.countDown发生在成功"获取"之后的动作之前。另一个线程中同一个同步器对象上的Lock.lock,Semaphore.acquire,Condition.await和CountDownLatch.await等方法。
答案 1 :(得分:0)
奥列格说。 synchronized关键字既表示块不能并行执行,也表示存储器将被同步,即写入主存储器。
这意味着在上面的代码中向count变量添加synchronized或volotile不会做任何事情,因为count变量只能在同步的部分中访问。
答案 2 :(得分:0)
根据: -
当同步方法退出时,它会自动建立 与任何后续调用a之前发生的关系 同一对象的同步方法。这保证了变化 所有线程都可以看到对象的状态。
因此,一旦线程放弃锁定,所有缓存都会被刷新并且与主内存同步更改。因此,在上面的代码中,我们不需要为实例变量使用volatile关键字。