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.强行制造一个异常