废话不多说,直接粘测试代码
public class Test{
public static void main(String[] args) {
try {
ThreadB tb = new ThreadB();
tb.start();
System.out.println("0");
synchronized (tb) {
System.out.println("3");
tb.wait();
System.out.println("4");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class ThreadB extends Thread {
@Override
public void run() {
synchronized (this) {
System.out.println("1");
notify();
System.out.println("2");
}
}
}
为什么输出结果
有时候是:
0
1
2
3
有时候是:
0
1
2
3
4
public class Test{ public static void main(String[] args) { try { ThreadB tb =...
其实你还少说了一种可能,即:0,3,1,2,4.
对于0,1,2,3来说,首先main线程输出0没有疑问,接下来tb获得对象自身的锁,而main线程在竞争tb对象自身的锁时失败处于阻塞状态,因此执行tb线程的run方法,输出1,调用notify方法,输出2,释放自身对象锁,main线程获得tb对象锁,输出3,调用wait方法,此时存在两种情况:
若nitify方法通知过早,则main线程一直处于wait状态,整个程序不会结束,整个输出为0,1,2,3
若notify方法在main线程调用wait方法之后到达,则输出4,main线程释放对象锁,主程序结束,输出为:0,1,2,3,4
若main线程先获取到tb对象锁,输出3,之后处于wait状态,释放tb对象锁,此时tb线程获取对象锁,输出2,调用notify通知处于wait状态的main线程,输出3之后释放对象锁,此后main得到对象锁,执行wait之后的语句,输出4,
整个输出为0,3,1,2,4.
同意这个说法,其实你还少说了一种可能,即:0,3,1,2,4.
对于0,1,2,3来说,首先main线程输出0没有疑问,接下来tb获得对象自身的锁,而main线程在竞争tb对象自身的锁时失败处于阻塞状态,因此执行tb线程的run方法,输出1,调用notify方法,输出2,释放自身对象锁,main线程获得tb对象锁,输出3,调用wait方法,此时存在两种情况:
若nitify方法通知过早,则main线程一直处于wait状态,整个程序不会结束,整个输出为0,1,2,3
若notify方法在main线程调用wait方法之后到达,则输出4,main线程释放对象锁,主程序结束,输出为:0,1,2,3,4
若main线程先获取到tb对象锁,输出3,之后处于wait状态,释放tb对象锁,此时tb线程获取对象锁,输出2,调用notify通知处于wait状态的main线程,输出3之后释放对象锁,此后main得到对象锁,执行wait之后的语句,输出4,
整个输出为0,3,1,2,4.
只有在wait命令执行在notify前面才会出现0 1 2 3 4
我感觉是一个bug啊,
package test;
public class Test {
public static final Object lock = new Object();
public static ThreadB lock2;
public static void main(String[] args){
try {
lock2 = new ThreadB();
lock2.start();
System.out.println("0");
synchronized (lock) {
System.out.println("3");
lock.wait();
System.out.println("4");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class ThreadB extends Thread {
@Override
public void run() {
synchronized (Test.lock) {
System.out.println("1");
Test.lock.notify();
System.out.println("2");
}
}
}
这个代码将互斥量改成lock 就会错失notify信息,符合我的想法。
如果将互斥量改成线程本身lock2,wait和notify就好像失效了一样,很神奇、、、我也不知道为什么
刚看了一下JDK中关于Object对象wait和notify方法的描述,找到如下语句:
代码修改如下:
public class Test{
public static void main(String[] args) {
try {
ThreadB tb = new ThreadB();
tb.start();
System.out.println("0");
synchronized (tb) {
System.out.println("3");
while(true) {
System.out.println("4");
tb.wait();
System.out.println("虚假唤醒情况");
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
ThreadB类保持不变
我感觉一个线程消亡后,会自动调用该线程的notify(),我猜的
package test;
public class Test {
public static void main(String[] args){
try {
ThreadB tb = new ThreadB();
tb.start();
System.out.println("0");
synchronized (tb) {
System.out.println("3");
tb.wait();
System.out.println("4");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class ThreadB extends Thread {
@Override
public void run() {
System.out.println("1");
System.out.println("2");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
你这代码不知道要干啥,完全没有同步和互斥的作用。你是想打印出1 2 3 4吗?