java多线程与线程池技术讲解(三)

第三章 线程之间的通信

3.1.1 阻塞当前线程
public static void main(String[] args) {
        //定义锁
        Object o = new Object();
        //新建阻塞线程
        new Thread(()->{
            //新建任务
            //循环10次
            for (int i=0;i<10;i++){
                //打印日志
                System.out.println(Thread.currentThread().getId()+",i="+i);
                //循环到第5次的时候
                if (i==5){
                    //获取锁
                    synchronized (o){
                        //打印日志
                        try {
                            System.out.println(Thread.currentThread().getId()+",开始等待...");
                            //当前线程进入等待
                            o.wait();
                            //当前线程进入阻塞
                            //打印当前线程的状态
                        }catch (Exception e){

                        }
                    }
                }
            }
            //启动这个线程
        }).start();

        //新建唤醒线程
        new Thread(()->{
            //新建唤醒任务
            //打印日志
            System.out.println(Thread.currentThread().getId()+"running...");
            //延迟一秒种
            try{
                //获取锁延迟一秒钟,不然这个线程会抢先执行
                Thread.sleep(1000);
                synchronized (o){
                    //打印日志
                    System.out.println(Thread.currentThread().getId()+",发送notify通知...");
                    //发送唤醒通知
                    o.notify();
                }
            }catch (Exception e){

            }
            //启动线程
        }).start();

    }
  • 不管调用wait方法还是notify方法,都要先获取锁。总结来说:如果没有锁,线程的执行顺序是不确定的,那么有可能notify线程会优先于wait线程执行,导致wait唤醒失败。
3.1.2 案例分析
3.2 join线程排队
  1. 线程a调用线程b对象的join方法,会导致线程a的允许中断,知道b运行完毕,线程a才继续运行。(插队)
static class Worker extends Thread{
     private UrgentTask joiner;
     public void run(){
         int i=0;
         while (i<9){
             try {
                 if (i == 8){
                     UrgentTask urgent = joiner;
                     System.out.println("突然接到了紧急工作,需要去处理");
                     urgent.start();
                     urgent.join();
                 }
                 //延时加载
                 TimeUnit.SECONDS.sleep(1);
                 i+=2;
             }catch (InterruptedException e){
                 e.printStackTrace();
             }
         }
         System.out.println("我已完成了日常工作,完成度100%。。。");
     }
     public void setJoiner(UrgentTask joiner){
         this.joiner = joiner;
     }
 }

 static class UrgentTask extends Thread{
     public void run(){
         int i=0;
         while (i<9){
             try {
                 System.out.println("紧急任务处理,完成度"+(i*10)+"%");
                 TimeUnit.SECONDS.sleep(1);
                 i+=3;
             }catch (InterruptedException e){
                 e.printStackTrace();
             }
         }
         System.out.println("紧急任务完成度为"+"100%");
     }
 }

    public static void main(String[] args) {
        try {
            Worker worker = new Worker();
            UrgentTask j = new UrgentTask();
            worker.start();
            //延时加载
            TimeUnit.SECONDS.sleep(3);
            worker.setJoiner(j);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
3.3线程中断

如果想停止一个正在运行中的线程,可以尝试使用**interrupt()**方法,interrupt()方法并不能马上停止线程的运行,它只是给线程设置一个中断状态值,线程是否能够停止,由操作系统和cpu决定。

3.3.1中断运行态线程
public static void main(String[] args) {
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i=0;i<10;i++){
                    if (Thread.currentThread().isInterrupted()){
                        System.out.println("收到中断通知,结束线程....");
                        break;
                    }else {
                        System.out.println(Thread.currentThread().getId()+",i="+i);
                        try {
                            Thread.sleep(100);
                        }catch (Exception e){}
                    }
                }
            }
        });
        t.start();
        try {
            Thread.sleep(500);
        }catch (Exception e){}
        t.interrupt();
        System.out.println(t.getId()+"中断状态:"+t.isInterrupted());
    }
  1. 总结:处于waitting阻塞态和休眠阻塞态的线程,调用interrupt()方法会抛出interruptedException异常。
3.4 CountDownLatch计数器
  1. 用于运行一个或多个线程阻塞等待,直到其他线程工作完毕才开始执行。
3.5 CyclicBarrier屏障
  1. 屏障能够让所有的并行任务都在CyclicBarrier屏障处停止。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值