thread的wait notifyAll notify 只能在同步代码中调用。
wait 释放当前的锁,并进入等待状态,如果没有别的线程调用notifyall 或者notify() 则会一直处于等待状态:
public class SynDemo {
private Object lock;
public SynDemo(Object lock) {
this.lock = lock;
}
public void test1(){
synchronized (lock){
System.out.println("test1 is running1");
try {
Thread.sleep(2000);
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("test1 is running2");
}
}
public void test2() {
synchronized (lock){
System.out.println("test2 is running1");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
lock.notify();
System.out.println("test2 is running2");
}
}
}
调用:
Object lock = new Object();
Thread third = new Thread(()->{
SynDemo demo = new SynDemo(lock);
demo.test1();
});
third.start();
Thread five = new Thread(()->{
SynDemo demo = new SynDemo(lock);
demo.test2();
});
five.start();
打印结果:
test1 is running1
test2 is running1
test2 is running2
test1 is running2
线程third 中调用test1方法,首先获得同步锁,然后休眠了2秒,这个时候还占用着同步锁,之后调用wait,释放同步锁,线程five中的test2获得同步锁,调用lock.notify();唤醒线程third,但是five并没有释放锁,而是等在执行完之后,third才获得锁。由此可见调用了notify之后,并不会释放锁,只是唤醒被wait的线程而已。
notify()和notifyAll的区别是,notify只会随机的唤醒一个线程,notifyAll唤醒全部wait的线程,所以在实际使用的时候尽量使用notifyAll。
Java线程中的join的意义在于等我执行完你在执行。
Thread first = new Thread(() -> {
System.out.println("first start running ");
Thread second = new Thread(() -> {
System.out.println("Second is running");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
second.start();
try {
second.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("first end running");
});
first.start();
结果:
first start running
Second is running
first end running
意思说first线程执行到second.join()之后,等到second执行完了之后在继续执行
看join的源码很有意思,并且还有点绕。
public final void join() throws InterruptedException {
join(0);
}
public final synchronized void join(long millis)
throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (millis == 0) {
while (isAlive()) {
wait(0);
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
可以看到join调用了join(0)这个方法,并且这个join(0)这个方式是synchronized的,也就是同步的。需要注意的是这个join方法是由first来调用的。 继续往下传进来的参数是0,所以会进入一个下面这个循环
while (isAlive()) {
wait(0);
}
如果是true的话,表示的是当前线程进入wait,也就是释放锁,让出CPU,所以当前的线程就是不会往下执行了。 而这个isAlive()判断是second的线程有没有执行完,如果执行完了也就返回false了就退出循环,然后first开始继续执行。
thead.yeild()方法会让线程暂时的释放CPU资源。然后所有的线程在同时竞争CPU资源,当然调用thread.yeild()也会重新参与竞争CPU资源。所以他的意思是让资源重新调度一次。 但是如果有同步锁,yeild()方法不会释放同步锁,所以如果有多个线程在等待同步锁,yeild方法不会释放同步锁,等待同步锁线程还是不会执行,那么还是当前线程得到CPU执行。
同样的还有sleep方法,sleep方法既不会释放CPU资源也不会释放同步锁。
欢迎关注我的公众号: manong_xiaodong或扫一扫下面的二维, 有大数据资料赠送哟,因为我最近也在学习大数据!欢迎一起学习!