用同步块替换volatile不起作用 [英] Replacing volatile with synchronized block is not working

查看:82
本文介绍了用同步块替换volatile不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读教程.我了解了易失性关键字的用法.但是,当我尝试在不使用volatile关键字的情况下对同步块中的关注变量进行操作时达到相同的结果时,它不起作用.它引发IllegalMonitorStateException.这是我尝试过的修改后的代码.

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. It throws 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(); }
        }
    }
}}}

我想知道的是,在这种情况下,可以使用同步块替换掉volatile,如果是的话该怎么做? 谢谢.

What I want to know is, in this case is volatile replaceable with synchronized block, if yes then how to do that? Thanks.

推荐答案

问题在这里:

 MY_INT = ++local_value;

MY_INT是一个Integer变量,当您为其分配新值时,您将在此处锁定的对象

MY_INT is an Integer variable, and when you assign a new value to it, the object that you are locking here:

 synchronized(MY_INT){

将与您在此处通知的对象不同:

will be different to the object that you are notifying here:

  MY_INT.notify();

...这将导致异常.

... and that will lead to the exception.

解决方案是使锁对象为static final.显然,这意味着您不能分配给它...但这就是重点!

The solution is to make the lock object static final. Obviously that means you can't assign to it ... but that is the whole point!

这篇关于用同步块替换volatile不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆