集团主站
欢迎来到成都达内官方网站!达内—美国上市公司 亿元级外企IT培训企业!
成都it培训哪家好
成都it培训哪家好
全国服务监督电话:400-111-8989  |   联系客服   |
当前位置:主页 > 培训课程 > Java >

成都java培训:什么是等待通知机制?

发布者: 成都达内     浏览次数:     发布时间:2021-03-22 10:05:15

成都java培训:在多线程编程中,可能A线程的条件没有满足只是暂时的,稍后其他的线程B可能会更新条件使得A线程的条件得以满足,可以将A线程暂停,直到它的条件得到满足之后再将...

  在单线程中,要执行的操作需要满足一定条件才能执行,可以把这个操作放在if语句块中。

  在多线程编程中,可能A线程的条件没有满足只是暂时的,稍后其他的线程B可能会更新条件使得A线程的条件得以满足,可以将A线程暂停,直到它的条件得到满足之后再将A线程唤醒

  Atomic{

  while(条件不成立)

  {

  等待

  }

  条件满足后,当前线程被唤醒

  }

  等待通知机制的实现object类中的Wait方法可以使当前线程的代码暂停执行,直到接到通知或者被中断为止

  注意:

  (1)wait方法只能再同步代码块中由锁对象调用

  (2)调用wait方法,当前线程会释放锁

  public class Text16_5 {

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

  String text="hello";

  System.out.println("同步前代码块");

  synchronized (text)

  {

  System.out.println("同步代码块开始");

  text.wait();

  System.out.println("同步代码块结束");

  }

  System.out.println("全部结束");

  }

  }

  因为调用了锁对象的wait方法,会释放锁对象,处于等待的状态,没有被唤醒就会一直等待下去。

  object类的notify方法可以唤醒线程,该方法也必须同步在代码块中,由锁对象调用,没有使用锁对象调用wait/notify会报出IIegalMonuitorStateExeption异常,如果由多个等待的线程,notify方法只能唤醒其中的一个,在同步代码块中调用notify方法后,并不会立即释放锁对象,需要等当前同步代码块执行完后才会释放锁对象,一般将notify放在同步代码块最后。

  synchronized(锁对象)

  {

  //执行修改保护条件的代码

  //唤醒其他线程

  锁对象.notify();

  }

  public class TextNotify {

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

  String text="hello";

  Thread t1=new Thread(new Runnable() {

  @Override

  public void run() {

  synchronized (text)

  {

  System.out.println("同步代码块开始");

  try {

  text.wait();//线程等待

  } catch (InterruptedException e) {

  e.printStackTrace();

  }

  System.out.println("同步代码块结束");

  }

  }

  });

  Thread t2=new Thread(new Runnable() {

  @Override

  public void run() {

  synchronized (text)

  {

  System.out.println("线程开始唤醒");

  text.notify();

  System.out.println("线程结束唤醒");

  }

  }

  });

  t1.start();//开启t1线程 t1等待

  Thread.sleep(3000);//睡眠3秒 确保t1处于等待状态

  t2.start();//唤醒t1线程

  }

  }

  notify不会立即释放锁对象案例:

  import java.util.ArrayList;

  import java.util.List;

  public class NotifyText2 {

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

  List strings=new ArrayList<>();

  Thread t1=new Thread(new Runnable() {

  @Override

  public void run() {

  synchronized (strings)

  {

  System.out.println("线程1开始等待");

  try {

  strings.wait();

  } catch (InterruptedException e) {

  e.printStackTrace();

  }

  System.out.println("线程1被唤醒");

  }

  }

  });

  Thread t2=new Thread(new Runnable() {

  @Override

  public void run() {

  synchronized (strings)

  {

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

  strings.add("data"+i);

  System.out.println("线程2添加了"+(i+1));

  if(strings.size()==5)

  {

  strings.notify();

  System.out.println("线程2被唤醒");

  }

  }

  }

  }

  });

  t1.start();

  Thread.sleep(1000);

  t2.start();

  }

  }

  线程2的代码还没有执行完毕,锁没有立即释放依然在执行,需要等到所有代码块全部执行完毕才释放

  interrupt会中断线程的等待public class InterruptText {

  private static final String name=new String();

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

  Thread t1=new Thread(new Runnable() {

  @Override

  public void run() {

  synchronized (name)

  {

  try {

  System.out.println("同步代码块开始");

  name.wait();

  System.out.println("同步代码块结束");

  } catch (InterruptedException e) {

  System.out.println("wait被中断"+e);

  }

  }

  }

  });

  t1.start();

  Thread.sleep(2000);

  t1.interrupt();

  }

  }

  原来锁对象需要执行完同步代码块才能释放锁对象,在执行过程如果遇到异常也会导致线程终止,释放锁对象。调用wait方法也会释放锁对象。

  notify与notifyAll的区别notify一次只能唤醒一个,如果有多个线程都在等待,只能随机唤醒其中的一个,想要唤醒所有等待线程需要调用notifyAll。

  public class InterruptText {

  private static final String name=new String();

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

  String str=new String();

  NotifyAll notifyAll=new NotifyAll(str);

  NotifyAll notifyAl2=new NotifyAll(str);

  NotifyAll notifyAll3=new NotifyAll(str);

  notifyAll.setName("线程一");

  notifyAl2.setName("线程二");

  notifyAll3.setName("线程三");

  notifyAll.start();

  notifyAl2.start();

  notifyAll3.start();

  Thread.sleep(2000);//休眠两秒

  synchronized (str)

  {

  //str.notify();只能随机唤醒一个

  str.notifyAll();//唤醒全部线程

  }

  };

  static class NotifyAll extends Thread

  {

  private String name;

  private NotifyAll(String name)

  {

  this.name=name;

  }

  @Override

  public void run() {

  synchronized (name)

  {

  try {

  System.out.println(Thread.currentThread().getName()+"同步代码块开始");

  name.wait();

  System.out.println(Thread.currentThread().getName()+"同步代码块结束");

  } catch (InterruptedException e) {

  System.out.println("wait被中断"+e);

  }

  }

  }

  }

  }

  如果只调用一次notify()之恶能唤醒其中的一个线程,其他等待线程依然处于等待状态,就错过了通知信号,这种现象称之为信号丢失。

  wait(Long)的使用带有参数的Wait(Long)方法,在指定时间内没有操作会被自动唤醒

(责任编辑:范老师)
最新开班
  • 成都Java培训班
    免费试听名额发放中...
  • 成都C++培训班
    免费试听名额发放中...
  • 成都PHP培训班
    免费试听名额发放中...
  • 成都网络工程培训班
    免费试听名额发放中...
  • 成都Unity3D培训班
    免费试听名额发放中...
  • 成都大数据培训班
    免费试听名额发放中...
  • 成都uid培训班
    免费试听名额发放中...
  • 成都会计培训班
    免费试听名额发放中...
  • 成都Python培训班
    免费试听名额发放中...
  • 成都嵌入式培训班
    免费试听名额发放中...
  • 成都web培训班
    免费试听名额发放中...
  • 成都软件测试培训班
    免费试听名额发放中...
在线留言
提交

校区地址:成都市锦江区东大街紫东楼端35号明宇金融广场19楼1906室

联系电话:400-111-8989

公交路线:芷泉街(18路;21路;43路;48路;104路;152路;335路 ) 地铁路线:东门大桥站(地铁2号线)

校区地址:成都市高新区奥克斯广场蜀锦路209号一楼商铺

联系电话:400-111-8989

公交路线:益州大道锦城大道口(18路;21路;43路;48路;104路;152路;335路 ) 地铁路线:孵化园(地铁1号线)

校区地址:成都锦江区东大街芷泉街229号东方广场C座3楼303

联系电话:400-111-8989

公交路线:芷泉街(188路;115路;515路;236路;505路;501路;84路 ) 地铁路线:东门大桥站(地铁2号线)

校区地址:成都市武侯区佳灵路3号红牌楼广场2号写字楼11楼1115号

联系电话:400-111-8989

公交路线:红牌楼东(11路;92路;100路;111路;139路;g28路;快速公交K1/K2) 地铁路线:红牌楼站(地铁3号线)

校区地址:成都市锦江区红星路二段70号四川日报大厦502-2

联系电话:400-111-8989

公交路线:市二医院站(6路;49路;102路;5路;37路;g92路;) 地铁路线:地铁市二医院(地铁3号线)

校区地址:成都市锦江区东大街芷泉段229号东方广场C座16层

联系电话:400-111-8989

公交路线:芷泉街(18路;21路;43路;48路;104路;152路;335路 ) 地铁路线:东门大桥站(地铁2号线)

校区地址:四川省成都市武侯区高新科技孵化园9号园区E座7楼

联系电话:400-111-8989

公交路线:益州大道锦城大道口(18路;21路;43路;48路;104路;152路;335路 ) 地铁路线:孵化园(地铁1号线)

了解达内动态
关注成都达内教育公众号

首页 | 关于达内 | 课程中心 | 专家师资 | 视频教程 | 学员空间 | 校企合作 | 新闻资讯 | 就业指导 | 网站地图

2016-2025 达内时代科技集团有限公司 版权所有 京ICP证8000853号-56 蜀ICP备18021046号-3