线程之间的通信

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值