首页 > 编程语言 > 详细

多线程学习---线程终止执行、线程睡眠

时间:2021-04-11 16:27:43      阅读:13      评论:0      收藏:0      [点我收藏+]

等待线程执行终止

  在项目中,往往需要多个等某几个事情完成之后才能继续执行,比如多个线程加载资源,需要等待多个线程全部加载完毕在做汇总。Thread类中提供了一个join()方法就可以完成这个事情,前面的等待通知等都是Object类中的方法,而join()方法是Thread类直接提供

public static void main(String[] args)throws Exception {
        Thread threadA=new Thread(){
            @Override
            public void run() {
                System.out.println("线程A执行");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("线程A执行完毕");
            }
        };
        Thread threadB=new Thread(){
            @Override
            public void run() {
                System.out.println("线程B执行");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("线程B执行结束");
            }
        };
        threadA.start();
        threadB.start();
        //等待线程执行完毕返回
        threadB.join();
        threadA.join();
     
     System.out.println("主线程汇总代码");
}

  代码中在主线程里面启动了两个子线程,然后分别调用了他们的join方法,那么主线程会调用threadA的join方法后被阻塞,等待threadA执行完毕后返回,然后主线程调用threadB的join方法被阻塞,等待threadB执行完毕返回,然后在执行两个线程调用join之后的代码

  另外,如果线程A调用了线程B的join方法后被阻塞了,当其他线程调用线程A的interrupt()方法中断了线程A时,线程A则会抛出InterruptedException异常而返回

public static void main(String[] args){
        Thread threadA=new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("线程A执行");
                for(;;){
                }
            }
        });
        Thread mainThread=Thread.currentThread();
        Thread threadB=new Thread(new Runnable() {

            @Override
            public void run() {
                System.out.println("线程B执行");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //主线程中断
                mainThread.interrupt();
            }
        });
        threadA.start();
        threadB.start();
        //等待线程执行完毕返回
        try {
            threadA.join();
        } catch (InterruptedException e) {
      System.out.println("main thread:"+e);
} }

     执行结果:

    技术分享图片

 

 

      代码中,threadA执行死循环,主线程调用了threadA的join方法阻塞了自己等待threadA执行完毕,待threadB休眠1秒后会调用主线程的interrupt()方法中断主线程,而从结果看在主线程中的threadA.join方法会抛出InterruptedException异常

线程的睡眠

 Thread类中有个静态的sleep方法,当一个执行的线程调用了Thread.sleep()方法后,调用的线程就会暂时让出执行权,这段时间不参与CPU调度,但是该线程所拥有的监视器资源锁还是持有不让出的,指定的睡眠时间到了后该线程会正常返回,处于就绪状态,然后参与CPU调度,获取到CPU资源后,继续运行。如果在睡眠期间,其他线程调用了该线程的interrupt()方法中断了该线程,则该线程会在调用sleep()方法的地方抛出InterruptedException异常

  举例:线程睡眠中,监视器资源不会被释放

public static void main(String[] args){
        //创建一个独占锁
        final Lock lock=new ReentrantLock();
        Thread threadA=new Thread(new Runnable() {
            @Override
            public void run() {
                lock.lock();
                try {
                    System.out.println("线程A等待10秒");
                    Thread.sleep(10000);
                    System.out.println("线程A等待结束");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {
                    lock.unlock();  //释放独占锁
                }
            }
        });
        Thread threadB=new Thread(new Runnable() {
            @Override
            public void run() {
                lock.lock();
                try {
                    System.out.println("线程B等待5秒");
                    Thread.sleep(5000);
                    System.out.println("线程B等待结束");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {
                    lock.unlock(); //释放独占锁
                }
            }
        });
        threadA.start();
        threadB.start();
    }

  执行结果: 

  技术分享图片

 

   上边代码先创建了一个独占锁,然后两个线程中,每个线程都先获取这个锁,然后睡眠,睡眠结束后释放锁。首先,无论执行多少遍代码,都不可能出现AB交叉等待的情况;从结果中看,线程A先获取到锁,那么A先输出一行,然后调用sleep睡眠10秒,在A睡眠的这10秒中,并没有释放锁,所以线程B无法获取到锁一直处于阻塞状态,等到A睡眠时间到了执行完unlock方法释放完锁,B才获取到锁继续执行

  

  举例:线程睡眠中,调用中断interrupt()

 

public static void main(String[] args){
        Thread threadA=new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    System.out.println("线程A等待10秒");
                    Thread.sleep(10000);
                    System.out.println("线程A等待结束");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        threadA.start();
        try {
            //主线程休眠2秒
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //中断子线程
        threadA.interrupt();
    }

  执行结果:

  技术分享图片

 

   代码中,子线程执行了sleep方法睡眠10秒中,在此期间主线程中断了子线程,所以子线程在调用sleep()方法的过程中抛出了interrupted异常

  注意:如果调用Thread.sleep(long millis)方法时,millis参数是个负数,则会直接抛出IllegalArgumentException异常

  

多线程学习---线程终止执行、线程睡眠

原文:https://www.cnblogs.com/jisha/p/14643348.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!