tra*_*t0r 0 java multithreading synchronized
我有一些像这样的代码:
public class HelloWorld {
public static void main(String[] args){
ThreadB b = new ThreadB();
b.start();
Runnable a = new Runnable(){
public void run(){
System.out.println(Thread.currentThread().getId());
synchronized(b){
try{
System.out.println("Waiting for b to complete...");
b.wait();
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println("Total is: " + b.total);
}
}
};
(new Thread(a)).start();
synchronized(b){
System.out.println(Thread.currentThread().getId());
try{
System.out.println("Waiting for b to complete...");
b.wait();
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println("Total is: " + b.total);
}
}
}
Run Code Online (Sandbox Code Playgroud)
ThreadB类:
class ThreadB extends Thread{
int total;
@Override
public void run(){
synchronized(this){
for(int i=0; i<100 ; i++){
total += i;
}
System.out.println("Total is: " + total);
notify();
}
}
}
Run Code Online (Sandbox Code Playgroud)
基本上,我有两个线程锁定Threadb对象b.当我运行代码时,我看到:
1
Waiting for b to complete...
22
Waiting for b to complete...
Run Code Online (Sandbox Code Playgroud)
这里的数字是线程ID,所以很明显,它们是不同的线程.此外,它们锁定的对象是相同的(b).但是,两者都能够进入同步块并等待对象.
怎么可能?
此外,如果我在threadB.run()方法中插入2个其他行:
class ThreadB extends Thread{
int total;
@Override
public void run(){
synchronized(this){
for(int i=0; i<100 ; i++){
total += i;
}
System.out.println("Total is: " + total);
notify();
}
}
}
Run Code Online (Sandbox Code Playgroud)
2个线程运行完成:
Total is: 4950
22
1
Waiting for b to complete...
Waiting for b to complete...
Total is: 4950
Total is: 4950
Run Code Online (Sandbox Code Playgroud)
似乎在ThreadB.run()的旧定义中,等待线程错过了通知信号,因此它们无限期地等待.这是对的吗?
此外,如果一个线程退出而没有调用notify(),则内部释放锁(相当于notifyAll()).是对的吗?
因为调用Object.wait()会释放锁定.从文档:
当前线程必须拥有此对象的监视器.线程释放此监视器的所有权并等待,直到另一个线程通过调用notify方法或notifyAll方法通知等待此对象监视器的线程唤醒.然后线程等待,直到它可以重新获得监视器的所有权并继续执行.
似乎在ThreadB.run()的旧定义中,等待线程错过了通知信号,因此它们无限期地等待.这是对的吗?他们wait()直到他们notify()(可能发生虚假)或他们被打断.
此外,如果一个线程退出而没有调用notify(),则内部释放锁(相当于notifyAll()).是对的吗?一旦线程进入wait(),锁定就已经释放.