多线程的常用方法——休眠、让步、优先级、打断、插入、守护线程

一、线程的休眠

使用线程的sleep()可以使线程休眠指定的毫秒数,在休眠结束的时候继续执行线程。

public class SleepThread extends Thread{
        @Override
        public void run(){
            String[] names=new String[]{"zs","ls","ww","z6"};
            int index=(int)(Math.random()*4);
            for(int i=3;i>0;i--){
                System.out.println(i);
                try{
                    //Thread.sleep(1000);
                    TimeUnit.SECONDS.sleep(1);
                }catch (InterruptedException e){
                    e.printStackTrace();
                }
                System.out.println("倒计时"+i);
            }
            System.out.println("抽中学员为"+names[index]);
        }
}
public class TestSleep {
    public static void main(String[] args) {
        SleepThread thread=new SleepThread();
        thread.start();
    }
}
  • 其它线程可以使用interrupt方法打断正在睡眠的线程,这是sleep方法会抛出InterruptedException。
  • 建议用TimeUnit的sleep代替了Thread的sleep来获得更好的可读性。其底层还是sleep方法。
  • 在循环访问锁的过程中,可以加入sleep让线程阻塞时间,防止大量占用CPU资源。

二、线程的让步

  • Thread.yield()方法作用是:暂停当前正在执行的线程对象(及放弃当前拥有的cpu资源),并执行其他线程。
  • yield()做的是让当前运行线程回到可运行状态,以允许具有相同优先级的其它线程获得运行机会。因此,使用yield()的目的是让相同优先级的线程之间能适当的轮转执行。但是,实际中无法保证yield()达到让步目的,因为让步的线程还有可能被线程调度程序再次选中。

注意:yield()方法并不能保证线程一定会让出CPU资源,它只是一个 提示,告诉调度器当前线程愿意让出CPU资源。具体是否让出CPU资源,还是由调度器决定。

sleep()和yield()的区别

sleep()使当前线程进入停滞状态,所以执行sleep()的线程在指定的时间内肯定不会被执行;yield()只是使当前线程重新回到可执行状态,所以执行yield()的线程有可能在进入到可执行状态后马上又被执行。

sleep 方法使当前运行中的线程睡眠一段时间,进入不可运行状态,这段时间的⻓短是由程序设定的,yield 方法使当前线程让出 CPU 占有权,但让出的时间是不可设定的。实际上,yield()方法对应了如下操作:先检测当前是否有相同优先级的线程处于同可运行状态,如有,则把 CPU 的占有权交给此线程,否则,继续运行原来的线程。所以yield()方法称为“退让”,它把运行机会让给了同等优先级的其他线程
另外,sleep 方法允许较低优先级的线程获得运行机会,但 yield() 方法执行时,当前线程仍处在可运行状态,所以,不可能让出较低优先级的线程些时获得 CPU 占有权。在一个运行系统中,如果较高优先级的线程没有调用 sleep 方法,又没有受到 I\O 阻塞,那么,较低优先级线程只能等待所有较高优先级的线程运行结束,才有机会运行。

 三、线程的优先级

可以通过传递参数给线程的setPriority()来设置线程的优先级别,调整线程优先级:java线程有优先级,优先级高的线程会获得较多的运行机会。优先级:只能反映线程的 中或者是 紧急程度,不能决定是否一定先执行。

Java线程的优先级用整数表示,取值范围是1~10。

 四、线程打断

public void interrupt()

 实例方法interrupt()仅仅是设置线程的中断状态为true,不会停止线程。

public boolean isInterrupted()

 通过检查中断标志位,判断当前线程是否被中断。

public static boolean interrupted()

 静态方法,判断线程是否被中断,并清除当前中断状态

也就是说这个方法做了两件事:

  1. 返回当前线程的中断状态
  2. 将当前线程的中断状态设为false

当前线程的中断标识为true,就立刻停止了吗?

中断只是一种协同机制,只修改中断标识位而已,不会立刻停止线程。

如何使用中断标识优雅地停止线程?

 

 

 

 

 

 

 

 

 

 

 

 五、线程的合并(插入线程)

Thread中,join()方法的作用是调用线程等待该线程完成后,才能继续往下运行。

join是Thread类的一个方法,启动线程后直接调用,即join()的作用是:“等待该线程终止”,这里需 要理解的就是该线程是指的主线程等待子线程的终止。也就是在子线程调用了join()方法后面的代 码,只有等到子线程结束了才能执行。

总结join()方法:主线程的执行会被打断,直到新加入的线程执行完毕,主线程才继续

为什么要用join()方法

在很多情况下,主线程生成并启动了子线程,如果子线程里要进行大量的耗时的运算,主线程往往将于子线程之前结束,但是如果主线程处理完其他的事务后,需要用到子线程的处理结果,也就是主线程需要等待子线程执行完成之后再结束,这个时候就要用到join()方法了。

六、守护线程

  • 默认情况下我们创建的线程都是用户线程(普通线程),进程需要等待所有的线程执行完毕后,进程才会结束。
  • 守护线程 .setDaemon(true):设置守护线程。
  • 想要查看线程到底是用户线程还是守护线程,可以通过Thread.isDaemon()方法来判断,如果返回的结果是true则为守护线程,反之则为用户线程。
  • 当所有的用户线程退出后,守护线程会立马结束。

应用

  • 垃圾回收器线程属于守护线程
  • Tomcat用来接受处理外部的请求的线程就是守护线程。

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

进击的女IT

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值