synchronized关键字和实例方法上的锁

时间:2015-03-30 11:20:19

标签: java multithreading synchronized

我正在研究并发性,而我正在学习阻止线程。

我知道当相应的附加任务试图访问因另一个线程获得锁定而被锁定的方法时,线程可能会进入阻塞状态。

从我读过的任务块开始,等到它可以访问该方法,然后继续其业务(即run()方法的其余部分)。

那么为什么这个代码退出就像任务可以调用syn.getI()并访问"错误的" state(即使syn.manipulate()方法被锁定,所以我假设任务无法调用getI())?我在哪里错了?

public class SynchronizedClass {
    private int i;
    private boolean flag=true;
    public SynchronizedClass(int i){
        this.i=i;
    }
    public int getI(){
        return i;
    }
    public boolean getFlag(){
        return flag;
    }
    public synchronized void manipulate(){
        i=(i*2)+1;  //odd number
        Thread.yield();
        i= i+1; //even number       
    }
    public void close(){
        flag=false;
    }

}
public class MyThread implements Runnable {
    //auto-managed runnable
    Thread t;
    SynchronizedClass syn;
    public MyThread(SynchronizedClass syn){
        this.syn=syn;
        t=new Thread(this);
        t.start();
    }
    @Override
    public void run() {
        while(syn.getFlag()==true){
            syn.manipulate();
            if (syn.getI()%2!=0){
                syn.close();
                System.out.println("exit");
            }

        }

    }
    public static void main(String[] args) {
        SynchronizedClass syn = new SynchronizedClass(1);
        for(int i=0;i<4;++i)
            new MyThread(syn);
    }
}

1 个答案:

答案 0 :(得分:2)

  

即使syn.manipulate()方法被锁定,我也假设任务无法调用getI()

这就是你所犯的错误,我相信。

仅仅因为一个方法已同步,并不隐含意味着其他任何内容都是同步的。它不像拥有与对象关联的监视器的一个线程阻止其他线程访问该对象 - 它只是阻止其他线程获取监视器。

如果您使getI()方法同步,然后由于manipulate()而拥有监视器的一个线程意味着在同一对象上调用getI()的其他线程将必须等待才能获得监视器。