package demo8;
import java.util.Scanner;
class Processor {
public Object lock = new Object();
public void comsumer() {
System.out.println("coming into producer");
Scanner scan = new Scanner(System.in);
try {
Thread.sleep(2000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
synchronized (this) {//这里改为lock对象运行会出错,没搞明白
System.out.println("put a word to run notify() : ");
scan.nextLine();
notify();
System.out.println("after notify()");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("after three seconds");
}
public void producer() {
synchronized (this) {//这里改为lock对象运行会出错,没搞明白
System.out.println("coming into comsumer");
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("after wait");
}
}
}
public class App {
public void doWork() {
final Processor processor = new Processor();
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
processor.producer();
}
});
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
processor.comsumer();
}
});
thread1.start();
thread2.start();
}
public static void main(String[] args) {
App app = new App();
app.doWork();
}
}
这个代码可以直接运行,问题在请看代码注释。
------解决方案--------------------
wait() 和 notify() 都是object中的方法,是对象锁!直接调用,其实暗含了一个this,锁的对象是processor (final Processor processor = new Processor();),而你同步的是lock这个对象。在使用lock对象的时候,修改为lock.wait();和lock.notify();就可以正常运行。
------解决方案--------------------
当你使用的是synchronized关键字的时候,有两种方式,第一种是 同步方法,第二种是同步代码块,同步方法默认的锁就是this锁,同步代码块用的锁就是你加上去的锁,其中当你用到线程通信的时候,也就是 wait和notify机制的时候,wait和notify方法的所属对象是 锁对象,而不是this对象,也就是说,wait和notify是根据你加的锁的不同所属对象也是变化的,这也是为什么 wait和notify在 Object类中的原因, 如果 还不是 很清楚 ,建议还是看看,JDK5.0以后出现的 Lock和Condition 实现的线程间的 通信,那个结构更加清晰,可以帮助你理解这个,不过那个 性能更好
------解决方案--------------------
当你使用的是synchronized关键字的时候,有两种方式,第一种是 同步方法,第二种是同步代码块,同步方法默认的锁就是this锁,同步代码块用的锁就是你加上去的锁,其中当你用到线程通信的时候,也就是 wait和notify机制的时候,wait和notify方法的所属对象是 锁对象,而不是this对象,也就是说,wait和notify是根据你加的锁的不同所属对象也是变化的,这也是为什么 wait和notify在 Object类中的原因, 如果 还不是 很清楚 ,建议还是看看,JDK5.0以后出现的 Lock和Condition 实现的线程间的 通信,那个结构更加清晰,可以帮助你理解这个,不过那个 性能更好
wait() 和 notify() 都是object中的方法,是对象锁!直接调用,其实暗含了一个this,锁的对象是processor (final Processor processor = new Processor();),而你同步的是lock这个对象。在使用lock对象的时候,修改为lock.wait();和lock.notify();就可以正常运行。
我还是有点疑惑,那我以后在写同步块时到底该用this,还是lock对象呢。有什么区别吗?我还是理解的不够透彻。
------解决方案--------------------
当你使用的是synchronized关键字的时候,有两种方式,第一种是 同步方法,第二种是同步代码块,同步方法默认的锁就是this锁,同步代码块用的锁就是你加上去的锁,其中当你用到线程通信的时候,也就是 wait和notify机制的时候,wait和notify方法的所属对象是 锁对象,而不是this对象,也就是说,wait和notify是根据你加的锁的不同所属对象也是变化的,这也是为什么 wait和notify在 Object类中的原因, 如果 还不是 很清楚 ,建议还是看看,JDK5.0以后出现的 Lock和Condition 实现的线程间的 通信,那个结构更加清晰,可以帮助你理解这个,不过那个 性能更好
wait() 和 notify() 都是object中的方法,是对象锁!直接调用,其实暗含了一个this,锁的对象是processor (final Processor processor = new Processor();),而你同步的是lock这个对象。在使用lock对象的时候,修改为lock.wait();和lock.notify();就可以正常运行。
我还是有点疑惑,那我以后在写同步块时到底该用this,还是lock对象呢。有什么区别吗?我还是理解的不够透彻。