import javax.swing.*;
import java.awt.*;
import java.awt.event.*;class TestVolatile implements Runnable{
private volatile boolean flag = true;

private JFrame f;
private JButton b;
private JTextArea t;
private Object lock = new byte[0];

public TestVolatile(){
f = new JFrame("Test");
b = new JButton("Wait");
t = new JTextArea();
JScrollPane sp = new JScrollPane(t);
f.setBounds(0, 0, 400, 300);
f.add(b,BorderLayout.SOUTH);
f.add(sp,BorderLayout.CENTER);
b.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) {
flag = !flag;
if(flag == true){
b.setText("Wait");
synchronized (lock) {
lock.notifyAll();
}
}
else{
b.setText("Notify");
}
}

});

f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}


public void run(){
try {
while(true){ while(flag){
t.append("flag " + flag + "\n");
Thread.sleep(1000);
}

t.append("flag " + flag + "\n");
t.append("wait\n");

while(!flag){
synchronized (lock) {
lock.wait();
}
}

t.append("notify " + flag + "\n");
}

catch (Exception e) {}
}
}public class Test{
public static void main(String[] args) {
TestVolatile tv = new TestVolatile();
new Thread(tv).start();
}
}代码如上
问题1:可以将flag的修饰符volatile去掉吗 
问题2:监视器对象lock可以换成this吗

解决方案 »

  1.   


    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.*;class TestVolatile implements Runnable{
    private volatile boolean flag = true;

    private JFrame f;
    private JButton b;
    private JTextArea t;
    private Object lock = new byte[0];

    public TestVolatile(){
    f = new JFrame("Test");
    b = new JButton("Wait");
    t = new JTextArea();
    JScrollPane sp = new JScrollPane(t);
    f.setBounds(0, 0, 400, 300);
    f.add(b,BorderLayout.SOUTH);
    f.add(sp,BorderLayout.CENTER);
    b.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) {
    flag = !flag;
    if(flag == true){
    b.setText("Wait");
    synchronized (lock) {
    lock.notifyAll();
    }
    }
    else{
    b.setText("Notify");
    }
    }

    });

    f.setVisible(true);
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }


    public void run(){
    try {
    while(true){ while(flag){
    t.append("flag " + flag + "\n");
    Thread.sleep(1000);
    }

    t.append("flag " + flag + "\n");
    t.append("wait\n");

    while(!flag){
    synchronized (lock) {
    lock.wait();
    }
    }

    t.append("notify " + flag + "\n");
    }

    catch (Exception e) {}
    }
    }public class Test{
    public static void main(String[] args) {
    TestVolatile tv = new TestVolatile();
    new Thread(tv).start();
    }
    }
      

  2.   

    我给你测试了
    问题1:可以将flag的修饰符volatile去掉吗   
    答:可以
    问题2:监视器对象lock可以换成this吗
    答:你换成this后刚开始不会出现错误,在点一次按钮 线程处于等待状态了,在点按钮唤醒,程序会报错误
    Exception in thread "AWT-EventQueue-0" java.lang.IllegalMonitorStateException: current thread not owner
      

  3.   

    我给你测试了
    问题1:可以将flag的修饰符volatile去掉吗   
    答:可以
    问题2:监视器对象lock可以换成this吗
    答:你换成this后刚开始不会出现错误,在点一次按钮 线程处于等待状态了,在点按钮唤醒,程序会报错误
    Exception in thread "AWT-EventQueue-0" java.lang.IllegalMonitorStateException: current thread not owner
      

  4.   

    我用的是jdk1.6  当然我知道结果是什么  只不过我想知道为什么  
    Exception in thread "AWT-EventQueue-0" java.lang.IllegalMonitorStateException: current thread not owner
    要把所有的lock都换成this  不然监视器不一致了
    关于volatile,书上说由于执行效率的原因,处理器会拷贝一份本地变量到寄存器,这样可以直接在寄存器中对操作数进行判断,这样即使改变了本地变量的值,由于对本地变量的不可见性,while循环会继续执行,不过实际好像未必要把变量加上修饰符volatile?关于第二个互斥锁的问题,Object中的wait()会释放监视器的锁,然后在其他线程中调用notify或者notifyAll即可让中断的线程继续执行,那么this和程序中的lock有什么区别呢?
      

  5.   

    要沉了  
    重复下问题
    1:将volatile修饰符去掉的影响(请教volatile的更多含义)
    2:lock改成this以后为什么程序无法进行下去了
    请各位多多指教新手啊
      

  6.   

    代码可以直接拷贝运行,请指正代码中的BUG,谢谢了
      

  7.   

    匿名类内部要指明外部类的this引用  即TestVolatile.thisvolatile有请高人回答