多线程中常用的几种方法详解(run start yield join sleep....)

在此之前需要借助一个类,RunnableDemo,该类实现了Runnable接口.

public class RunnableDemo implements Runnable {
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+"   RunnableDemo");
    }
}

run()和start()

         * start():是启动一个新线程,需要首先被启动,而且不能被重复.它会自动启动run方法
         * run(): 和普通方法一样,线程启动后会自动调用run方法,可以重复调用.
         *
         * main MainThread
         * main   RunnableDemo
         * subThread   RunnableDemo
        RunnableDemo runnableDemo = new RunnableDemo();
        Thread subThread = new Thread( runnableDemo,"subThread" );
        System.out.println(Thread.currentThread().getName()+" MainThread");
        subThread.run(); //在主线程种调用 没有达到多线程的效果
        subThread.start(); //重新开辟一个新线程,它会自己调用run方法.
        //运行结果:main MainThread
        //        main   RunnableDemo        这个是主线程中调用的run
        //        subThread   RunnableDemo   这个是调用start方法,重新开辟的新线程

yield()

 /**
         * yield():让正在执行的线程从“运行状态”进入到“就绪状态”.
         * 线程进入可运行状态(Runnable状态),该状态分为两个子状态:运行(Running)和就绪状态(Runnable).
         * 运行状态是取得CPU周期并实际运行的,就绪状态是等待并争取使用CPU,这两个状态由运行调度器来控制.
         * 线程可以使用yield()方法自动从运行状态让位到排队状态.
         * 但是,并不能保证在当前线程调用yield()之后,
			其它具有相同优先级的线程就一定能获得执行权;
			也有可能是当前线程又进入到“运行状态”继续运行!
        RunnableDemo runnableDemo = new RunnableDemo();
        System.out.println(Thread.currentThread().getName()+" start");
        Thread subThread = new Thread( runnableDemo,"subThread" );
        subThread.start();
        Thread.yield();
        System.out.println(Thread.currentThread().getName()+" end");
        //运行结果为main start
        //        main end
        //        subThread   RunnableDemo
        //可以看出 在subThread线程调用了start方法后,它为当前正在执行的线程,
        // 当调用了yield后,让步于main线程了,等main线程执行完毕后,它又继续执行.*/

sleep()

sleep():让当前线程睡眠指定时间,在时间到达时自动回复线程的执行.它是Thread类的静态方法.参数填的是毫秒.
sleep方法不会释放线程锁.在线程重新被唤醒时,它会由“阻塞状态”变成“就绪状态”,从而等待CPU的调度执行
会抛出InterruptedException

join()

        * join():等待线程,将当前子线程加入到父线程中,该子线程执行完毕后父线程再继续执行.*/
        * 会抛出InterruptedException
        * 使用方法:在父线程中进行调用.join的原理是用wait做的,所以其行为类似于wait.
        RunnableDemo runnableDemo = new RunnableDemo();
        System.out.println(Thread.currentThread().getName()+" start");
        Thread subThread = new Thread( runnableDemo,"subThread" );
        subThread.start();  //重新启动一个新线程
        try {
            subThread.join();    //当前子线程加入到主线程中.先执行子线程.
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+" end");
        //没有join的结果:main start                 有join的结果:main start
        //             main end                               subThread   RunnableDemo
        //             subThread   RunnableDemo               main end
        //本来是主线程自己执行自己的,子线程自己执行自己的.相比之下主线程执行的快 
        // 加入join后,优先执行子线程再执行父线程.
        //interrupt :终止处于“阻塞状态”的线程,当线程由于被调用了
        	sleep(),wait(),join()等方法而进入阻塞状态,
        	若此时调用线程的interrupt()将线程的中断标记设为true,由于处于阻塞状态,
        	终端标记会被清除同时产生一个InterruptedException异常.将InterruptedException放在适当的位置就能终止线程.
        //isInterrupted() 判断中断是否发生,没有发生中断返回false,发生中断,返回true,并且把中断取消了.


        //setDaemon: 设定守护线程 java中有两种线程  守护线程和用户线程 而守护线程也就是"后台线程".一般用来执行后台任务.
          需要注意的是:java虚拟机在 "用户线程"都结束后会退出.
          守护线程的生命周期依赖于用户线程,用户线程全部退出后,守护线程就会自动结束.
        //isDaemon: 判断当前线程是否是守护线程
        

        //setPriority()  getPriority()
         线程优先级 来知道JVM层面优先来执行哪个程序,但最终执行顺序需要操作系统来指定
         java中的线程优先级范围是1-10 默认是5
         "高优先级线程"会优先于"低优先级线程"执行

一个例子来带你更加深入了解join的使用

假如有三个线程,t1 t2 t3将线程按照t3 t2 t1顺序执行

线程1 2 3 同时开始.为了保证3 2 1 的顺序执行
只需要让线程2等待线程3执行完后自己再执行
只需要让线程1等待线程2和3执行完后自己再执行
所以在线程2的run方法种 用上线程3.join
在线程1的run方法种 用上线程2.join

       RunnableDemo runnableDemo = new RunnableDemo();
       final Thread thread3 = new Thread( runnableDemo,"thread3" );
       final Thread thread2 = new Thread("thread2"){
           @Override
           public void run() {
               System.out.println(Thread.currentThread().getName()+" start");
               super.run();
               try {
                   thread3.join();
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
               System.out.println(Thread.currentThread().getName()+" end");
           }
       };

       Thread thread1 = new Thread( "thread1" ){
           @Override
           public void run() {
               System.out.println(Thread.currentThread().getName()+" start");
               super.run();
               try {
                   thread2.join();
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
               System.out.println(Thread.currentThread().getName()+" end");
           }
       };
       thread1.start();
       thread2.start();
       thread3.start();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值