线程之间的通信

来源:互联网 发布:手机淘宝账号申请注册 编辑:程序博客网 时间:2024/06/06 02:59

Java提供了3个非常重要的方法来巧妙地解决线程间的通信问题。这3个方法分别是:wait()、notify()和notifyAll()。它们都是Object类的最终方法,因此每一个类都默认拥有它们。

尽管在主方法中先启动了Consumer线程,但是,由于仓库中没有产品,因此,Consumer线程就会调用wait()方法进入等待队列进行等待,直到Producer线程将产品生产出来并放进仓库,然后使用notify()方法将其唤醒。

如何结束线程:
三种方式
1.使用flag标志位。 怎么结束run方法呢? 控制run方法当中的循环就可以了。 怎么控制循环呢? 在循环当中设置标志位,通过标志位来完成。 setFlag(false)

class StopRun implements Runnable{      private boolean flag = true;      public void setFlag(boolean flag) {          this.flag = flag;      }      @Override      public void run() {          while (flag) {              System.out.println(Thread.currentThread().getName()+".....run");          }      }  }  public class StopThreadDemo01 {      public static void main(String[] args) {          StopRun sRun = new StopRun();          Thread t1 = new Thread(sRun);          Thread t2 = new Thread(sRun);          t1.start();          t2.start();          int num = 0;          while (true) {              if (++num==50) {                  sRun.setFlag(false);                  break;              }              System.out.println(Thread.currentThread().getName()+".....run.."+num);          }          System.out.println("over");      }  }  

针对没有阻塞的情况:设置标志变量,让线程正常自然死亡,和谐!
针对有阻塞的情况:中断阻塞,靠抛出异常终止线程

2.interrupt方法
(1)如果线程在调用 Object 类的 wait()、wait(long) 或 wait(long, int) 方法,或者该类的 join()、join(long)、join(long, int)、sleep(long) 或 sleep(long, int) 方法过程中受阻,则其中断状态将被清除,它还将收到一个InterruptedException异常。这个时候,我们可以通过捕获InterruptedException异常来终止线程的执行,具体可以通过return等退出或改变共享变量的值使其退出。
(2)如果该线程在可中断的通道上的 I/O 操作中受阻,则该通道将被关闭,该线程的中断状态将被设置并且该线程将收到一个 ClosedByInterruptException。这时候处理方法一样,只是捕获的异常不一样而已。

如果在中断时,线程正处于非阻塞状态,则将中断标志修改为true,而在此基础上,一旦进入阻塞状态,则按照阻塞状态的情况来进行处理;例如,一个线程在运行状态中,其中断标志被设置为true,则此后,一旦线程调用了wait、jion、sleep方法中的一种,立马抛出一个InterruptedException,且中断标志被清除,重新设置为false。
通过上面的分析,我们可以总结,调用线程类的interrupted方法,其本质只是设置该线程的中断标志,将中断标志设置为true,并根据线程状态决定是否抛出异常。因此,通过interrupted方法真正实现线程的中断原理是:开发人员根据中断标志的具体值,来决定如何退出线程。

public void run() {              try {                  while (true){                      Thread.sleep(1000l);//阻塞状态,线程被调用了interrupte()方法,清除中断标志,抛出InterruptedException                      //dosomething                      boolean isIn = this.isInterrupted();                      //运行状态,线程被调用了interrupte()方法,中断标志被设置为true                      //非阻塞状态中进行中断线程操作                      if(isInterrupted()) break;//退出循环,中断进程                  }              }catch (InterruptedException e){//阻塞状态中进行中断线程操作                  boolean isIn = this.isInterrupted();//退出阻塞状态,且中断标志被清除,重新设置为false,所以此处的isIn为false                  return;//退出run方法,中断进程              }          }  

3.强行制造一个异常

原创粉丝点击