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吗
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吗
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吗
答:你换成this后刚开始不会出现错误,在点一次按钮 线程处于等待状态了,在点按钮唤醒,程序会报错误
Exception in thread "AWT-EventQueue-0" java.lang.IllegalMonitorStateException: current thread not owner
问题1:可以将flag的修饰符volatile去掉吗
答:可以
问题2:监视器对象lock可以换成this吗
答:你换成this后刚开始不会出现错误,在点一次按钮 线程处于等待状态了,在点按钮唤醒,程序会报错误
Exception in thread "AWT-EventQueue-0" java.lang.IllegalMonitorStateException: current thread not owner
Exception in thread "AWT-EventQueue-0" java.lang.IllegalMonitorStateException: current thread not owner
要把所有的lock都换成this 不然监视器不一致了
关于volatile,书上说由于执行效率的原因,处理器会拷贝一份本地变量到寄存器,这样可以直接在寄存器中对操作数进行判断,这样即使改变了本地变量的值,由于对本地变量的不可见性,while循环会继续执行,不过实际好像未必要把变量加上修饰符volatile?关于第二个互斥锁的问题,Object中的wait()会释放监视器的锁,然后在其他线程中调用notify或者notifyAll即可让中断的线程继续执行,那么this和程序中的lock有什么区别呢?
重复下问题
1:将volatile修饰符去掉的影响(请教volatile的更多含义)
2:lock改成this以后为什么程序无法进行下去了
请各位多多指教新手啊