java多线程notifyall_java多线程(7)wait()、notify()和notityALL()

wait

wait方法是Object中的方法,这个方法的功能特性:

1).执行wait方法的前提是当前线程已经获取到对象的锁,也就是wait方法必须在synchronized修饰的代码块或者方法中使用。

2).执行wait之后,会失去锁的所有权

3).wait方法执行后会一直等待,直到被调用notify()、notifyAll()或者所在线程被中断。

4).被调用notify()或者notifyAll()后,线程还是会等待,直到拥有锁的所有权,才会继续往下执行。

下面举个例子:

public static void main(String[] args) throws InterruptedException {

Object lock1 = new Object();

Thread t1 = new Thread(new Test().new Tt1(lock1));

Thread t2 = new Thread(new Test().new Tt2(lock1));

t1.start();

Thread.sleep(1000);

t2.start();

}

class Tt1 implements Runnable{

private Object lock1;

public Tt1(Object lock1) {

this.lock1 = lock1;

}

@Override

public void run() {

try {

System.out.println(this.getClass()+"-------1");

synchronized (lock1) {

Thread.sleep(2000);

System.out.println("waiting start");

lock1.wait();

}

System.out.println("waiting end");

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

class Tt2 implements Runnable{

private Object lock1;

public Tt2(Object lock1) {

this.lock1 = lock1;

}

@Override

public void run() {

System.out.println(this.getClass()+"-------1");

synchronized (lock1) {

try {

System.out.println(this.getClass()+"-------2");

lock1.notify();

Thread.sleep(1000);

System.out.println(this.getClass()+"-------3");

} catch (Exception e) {

e.printStackTrace();

}

}

}

}

执行结果:

class Test$Tt1-------1

class Test$Tt2-------1

waiting start

class Test$Tt2-------2

class Test$Tt2-------3

waiting end

分析一下:

第1、2行:t1和t2启动,t1先获取到锁所以t2一直被阻塞住

第3、4行:t1中执行了wait,锁被释放,所以t2继续执行下去。

第5、6行:t2中调用了notify()但是t1没有马上执行,因为锁现在是被t2拥有,等t2执行完成释放锁后,t1继续执行。

notify、notifyAll

notify已经在上面有提到过,notify和notifyAll 的作用是唤醒正在wait的线程,notify是随机唤醒wait线程中的一个,notifyAll 则是唤醒全部。

1).执行notify、notifyAll 方法的前提是当前线程已经获取到对象的锁,也就是必须在synchronized修饰的代码块或者方法中使用。这个和wait是一样的。

2).被调用notify()或者notifyAll()后,线程还是会等待,直到拥有锁的所有权,才会继续往下执行。

3)notify、notifyAll不会释放锁,这个与wait不同。

释放和不释放锁

在多线程的操作中,锁的释放与否是必须要清楚的,wait是会释放锁,而notify(notifyAll)则不会。先举个wait的例子:

public static void main(String[] args) throws InterruptedException {

Object lock1 = new Object();

Thread t1 = new Thread(new Test().new Tt1(lock1));

Thread t2 = new Thread(new Test().new Tt2(lock1));

t1.start();

Thread.sleep(100);

t2.start();

}

class Tt1 implements Runnable{

private Object lock1;

public Tt1(Object lock1) {

this.lock1 = lock1;

}

@Override

public void run() {

try {

synchronized (lock1) {

System.out.println(Thread.currentThread().getName()+"---start");

lock1.wait();

Thread.sleep(3000);

System.out.println(Thread.currentThread().getName()+"---end");

}

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

class Tt2 implements Runnable{

private Object lock1;

public Tt2(Object lock1) {

this.lock1 = lock1;

}

@Override

public void run() {

synchronized (lock1) {

try {

System.out.println(Thread.currentThread().getName()+"---start");

System.out.println(Thread.currentThread().getName()+"---end");

} catch (Exception e) {

e.printStackTrace();

}

}

}

}

执行结果:

Thread-0---start

Thread-1---start

Thread-1---end

Thread-0执行wait后马上释放了锁,所以Thread-1很快接着就执行。

再来notify的例子,其实就是把上一个例子wait()改成nofity():

public static void main(String[] args) throws InterruptedException {

Object lock1 = new Object();

Thread t1 = new Thread(new Test().new Tt1(lock1));

Thread t2 = new Thread(new Test().new Tt2(lock1));

t1.start();

Thread.sleep(100);

t2.start();

}

class Tt1 implements Runnable{

private Object lock1;

public Tt1(Object lock1) {

this.lock1 = lock1;

}

@Override

public void run() {

try {

synchronized (lock1) {

System.out.println(Thread.currentThread().getName()+"---start");

lock1.notify();

Thread.sleep(3000);

System.out.println(Thread.currentThread().getName()+"---end");

}

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

class Tt2 implements Runnable{

private Object lock1;

public Tt2(Object lock1) {

this.lock1 = lock1;

}

@Override

public void run() {

synchronized (lock1) {

try {

System.out.println(Thread.currentThread().getName()+"---start");

System.out.println(Thread.currentThread().getName()+"---end");

} catch (Exception e) {

e.printStackTrace();

}

}

}

}

执行结果:

Thread-0---start

Thread-0---end

Thread-1---start

Thread-1---end

可见Thread-0在执行nofity后并没有释放锁,而是等待代码块执行完之后才释放锁,Thread-1才能继续执行。

必须先获取锁

无论是notify还是wait都是要先获取锁,既必须在synchronized内使用,举个反例:

public static void main(String[] args) throws InterruptedException {

Object lock1 = new Object();

Thread t1 = new Thread(new Test().new Tt1(lock1));

t1.run();

}

class Tt1 implements Runnable{

private Object lock1;

public Tt1(Object lock1) {

this.lock1 = lock1;

}

@Override

public void run() {

try {

lock1.wait();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

执行结果:

Exception in thread "main" java.lang.IllegalMonitorStateException

at java.lang.Object.wait(Native Method)

at java.lang.Object.wait(Object.java:502)

at Test$Tt1.run(Test.java:24)

at java.lang.Thread.run(Thread.java:748)

at Test.main(Test.java:11)

wait()遇到interrupt()

之前说道interrupt(),并不会直接中断线程,而是会给线程一个中断标志,而且包括sleep、wait、join会抛出InterruptedException。

public static void main(String[] args) throws InterruptedException {

Object lock1 = new Object();

Thread t1 = new Thread(new Test().new Tt1(lock1));

t1.start();

Thread.sleep(100);

t1.interrupt();

}

class Tt1 implements Runnable{

private Object lock1;

public Tt1(Object lock1) {

this.lock1 = lock1;

}

@Override

public void run() {

synchronized (lock1) {

try {

System.out.println(Thread.currentThread().getName()+"---start");

lock1.wait();

System.out.println(Thread.currentThread().getName()+"---end");

}catch (InterruptedException e) {

System.out.println("线程被中断了");;

} catch (Exception e) {

e.printStackTrace();

}

}

}

}

执行结果:

Thread-0---start

线程被中断了

notifyAll和nofity

notifyAll和nofity唯一的不同就是,可以唤醒全部和唤醒一个, 先举个nofity的例子

public static void main(String[] args) throws InterruptedException {

Object lock1 = new Object();

Thread t1 = new Thread(new Test().new Tt1(lock1));

Thread t2 = new Thread(new Test().new Tt1(lock1));

Thread t3 = new Thread(new Test().new Tt2(lock1));

t1.start();

Thread.sleep(100);

t2.start();

Thread.sleep(100);

t3.start();

}

class Tt1 implements Runnable{

private Object lock1;

public Tt1(Object lock1) {

this.lock1 = lock1;

}

@Override

public void run() {

synchronized (lock1) {

try {

System.out.println(Thread.currentThread().getName()+"---start");

System.out.println(Thread.currentThread().getName()+"---wait");

lock1.wait();

System.out.println(Thread.currentThread().getName()+"---end");

} catch (Exception e) {

e.printStackTrace();

}

}

}

}

class Tt2 implements Runnable{

private Object lock1;

public Tt2(Object lock1) {

this.lock1 = lock1;

}

@Override

public void run() {

synchronized (lock1) {

try {

System.out.println(Thread.currentThread().getName()+"---start");

System.out.println(Thread.currentThread().getName()+"---notify");

lock1.notify();

System.out.println(Thread.currentThread().getName()+"---end");

} catch (Exception e) {

e.printStackTrace();

}

}

}

}

执行结果:

Thread-0---start

Thread-0---wait

Thread-1---start

Thread-1---wait

Thread-2---start

Thread-2---notify

Thread-2---end

Thread-0---end

Thread-0和Thread-1在wait,Thread-2执行了notify,但只有Thread-0被唤醒,重新开始执行,Thread-1还在wait。

再来看看nofityAll:

public static void main(String[] args) throws InterruptedException {

Object lock1 = new Object();

Thread t1 = new Thread(new Test().new Tt1(lock1));

Thread t2 = new Thread(new Test().new Tt1(lock1));

Thread t3 = new Thread(new Test().new Tt2(lock1));

t1.start();

Thread.sleep(100);

t2.start();

Thread.sleep(100);

t3.start();

}

class Tt1 implements Runnable{

private Object lock1;

public Tt1(Object lock1) {

this.lock1 = lock1;

}

@Override

public void run() {

synchronized (lock1) {

try {

System.out.println(Thread.currentThread().getName()+"---start");

System.out.println(Thread.currentThread().getName()+"---wait");

lock1.wait();

System.out.println(Thread.currentThread().getName()+"---end");

} catch (Exception e) {

e.printStackTrace();

}

}

}

}

class Tt2 implements Runnable{

private Object lock1;

public Tt2(Object lock1) {

this.lock1 = lock1;

}

@Override

public void run() {

synchronized (lock1) {

try {

System.out.println(Thread.currentThread().getName()+"---start");

System.out.println(Thread.currentThread().getName()+"---notifyAll");

lock1.notifyAll();

System.out.println(Thread.currentThread().getName()+"---end");

} catch (Exception e) {

e.printStackTrace();

}

}

}

}

执行结果:

Thread-0---start

Thread-0---wait

Thread-1---start

Thread-1---wait

Thread-2---start

Thread-2---notifyAll

Thread-2---end

Thread-1---end

Thread-0---end

Thread-2执行了notifyAll后,Thread-1和Thread-0都被唤醒。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值