java 多线程 notifyall_[笔记]Java多线程学习之wait,notify,notifyAll | 祭夜の咖啡馆

记录

this.notify();

功能:不是唤醒正在执行this.notify();的当前线程

而是唤醒一个现在正在等待(wait) this对象 的其它线程

如果有多个线程正在等待(wait) this对象 ,通常是唤醒最先等待(wait) this对象 的线程

但具体唤醒哪一个,是由系统调度器控制的,程序员无法控制

aa.wait();将执行aa.wait();的当前线程转入阻塞状态,让出CPU的控制权

释放对aa的锁定

需要被try catch包围,以便发生异常中断也可以使wait等待的线程唤醒。

aa.notify();假设执行aa.notify();的当前线程为T1,如果当前时刻有其他线程因为执行了aa.wait()而陷入阻塞状态,则唤醒其中一个

所谓唤醒是令该线程从因wait而陷入阻塞的状态转入就绪状态

若在执行aa.notify();前没有线程处于wait状态,那么程序也不会出错,相当于唤醒了0个线程

aa.notifyAll()唤醒其它所有的因执行了aa.wait()而陷入阻塞状态的线程

在多线程中要测试某个条件的变化,使用if 还是while?

选用while在多线程情况下,在wait过程中cnt可能会被其它线程修改,导致恢复后条件仍然成立

notify唤醒沉睡的线程后,线程会接着上次的执行继续往下执行。所以在进行条件判断时候,可以先把 wait 语句忽略不计来进行考虑;显然,要确保程序一定要执行,并且要保证程序直到满足一定的条件再执行,要使用while进行等待,直到满足条件才继续往下执行。

以下是简易的生产消费问题:

4275.air

public class produceConsume {

public static void main(String[] args) {

SynStack ss = new SynStack();

Producer p = new Producer(ss);

Consumer c = new Consumer(ss);

Thread t1 = new Thread(p); // 生产线程

Thread t2 = new Thread(c); // 消费线程

t1.start();

t2.start();

}

}

class SynStack {

private char[] data = new char[6];

private int cnt = 0; // 表示数组有效元素个数

public synchronized void push(char ch)

{

while(cnt == data.length) // 为什么不用if 【在多线程情况下,在wait过程中cnt可能会被其它线程修改,导致恢复后条件仍然成立】

{

// 暂停

try {

System.out.println("exc push wait");

this.wait();

} catch (Exception e) {

e.printStackTrace();

System.out.println("push wait error");

}

System.out.println("push resume");

}

this.notify();

data[cnt] = ch;

cnt++;

System.out.printf("生产线程正在生产第%d个产品:%c\n", cnt, ch);

}

public synchronized char pop()

{

char ch;

while(cnt == 0)

{

// 暂停

try {

// System.out.println("exc pop wait");

this.wait();

} catch (Exception e) {

System.out.println("pop error");

}

System.out.println("pop resume");

}

// System.out.println("awake");

this.notify();

ch = data[cnt - 1];

System.out.printf("消费线程正在消费第%d个产品:%c\n", cnt, ch);

--cnt;

return ch;

}

}

class Producer implements Runnable {

private SynStack ss = null;

public Producer(SynStack ss)

{

this.ss = ss;

}

public void run()

{

char ch;

for (int i = 0; i < 20; i++) {

// try {

// Thread.sleep(1000);

// } catch (Exception e) {

// e.printStackTrace();

// }

ch = (char)('a' + i);

ss.push(ch);

}

}

}

class Consumer implements Runnable {

private SynStack ss = null;

public Consumer(SynStack ss)

{

this.ss = ss;

}

public void run()

{

for (int i = 0; i < 20; i++) {

try {

Thread.sleep(1000);

} catch (Exception e) {

e.printStackTrace();

}

ss.pop();

}

}

}

祭夜の咖啡馆 , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权

转载请注明原文链接:[笔记]Java多线程学习之wait,notify,notifyAll

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值