简体   繁体   English

用同步块替换volatile不起作用

[英]Replacing volatile with synchronized block is not working

I was going through this tutorial. 我正在阅读教程。 I understood the volatile keyword usage. 我了解了可变关键字的用法。 But when i tried to achieve same result without using volatile keyword with doing operation on the concern variable with in synchronized block, it is not working. 但是,当我尝试在同步块中对关注变量进行操作而未使用volatile关键字的情况下达到相同的结果时,则无法正常工作。 It throws IllegalMonitorStateException. 它引发IllegalMonitorStateException。 Here is the modified code i tried. 这是我尝试的修改后的代码。

public class VolatileTest {
private static Integer MY_INT = 0;

public static void main(String[] args) {
    new ChangeListener().start();
    new ChangeMaker().start();
}

static class ChangeListener extends Thread {
    @Override
    public void run() {
         synchronized(MY_INT){
        int local_value = MY_INT;
        while ( local_value < 5){
            if( local_value!= MY_INT){
                System.out.format("Got Change for MY_INT : {0}", MY_INT);
                 local_value= MY_INT; 
                  try {
                MY_INT.wait();
            } catch (Exception e) { e.printStackTrace(); }}
            }
        }
    }
}

static class ChangeMaker extends Thread{
    @Override
    public void run() {
         synchronized(MY_INT){
        int local_value = MY_INT;
        while (MY_INT <5){
            System.out.format("Incrementing MY_INT to {0}", local_value+1);
            MY_INT = ++local_value;
            try {
                MY_INT.notify();
            } catch (Exception e) { e.printStackTrace(); }
        }
    }
}}}

What I want to know is, in this case is volatile replaceable with synchronized block, if yes then how to do that? 我想知道的是,在这种情况下,可以使用同步块替换掉volatile,如果是,那么该怎么做? Thanks. 谢谢。

The problem is here: 问题在这里:

 MY_INT = ++local_value;

MY_INT is an Integer variable, and when you assign a new value to it, the object that you are locking here: MY_INT是一个Integer变量,当您为其分配一个新值时,您将在此处锁定的对象:

 synchronized(MY_INT){

will be different to the object that you are notifying here: 将与您在此处通知的对象不同:

  MY_INT.notify();

... and that will lead to the exception. ...这将导致异常。


The solution is to make the lock object static final . 解决方案是使锁对象成为static final Obviously that means you can't assign to it ... but that is the whole point! 显然,这意味着您无法分配给它...但这就是重点!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM