五、线程状态管理

1、线程睡眠—sleep:
    线程睡眠的原因:线程执行的太快,或需要强制执行到下一个线程。   
线程睡眠的方法(两个):
      sleep(long millis)在指定的毫秒数内让正在执行的线程休眠。
      sleep(long millis,int nanos)在指定的毫秒数加指定的纳秒数内让正在执行的线程休眠。

线程睡眠的代码演示:

public class SynTest {
    public static void main(String[] args) {
        new Thread(new CountDown(),"倒计时").start();
    }
}

class CountDown implements Runnable{
    int time = 10;
    public void run() {
        while (true) {
            if(time>=0){
                System.out.println(Thread.currentThread().getName() + ":" + time--);
                try {
                    Thread.sleep(1000);                                                    //睡眠时间为1秒
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

每隔一秒则会打印一次,打印结果为:

倒计时:10
倒计时:9
倒计时:8
倒计时:7
倒计时:6
倒计时:5
倒计时:4
倒计时:3
倒计时:2
倒计时:1
倒计时:0

      扩展:Java线程调度是Java多线程的核心,只有良好的调度,才能充分发挥系统的性能,提高程序的执行效率。但是不管程序员怎么编写调度,只能最大限度的影响线程执行的次序,而不能做到精准控制。因为使用sleep方法之后,线程是进入阻塞状态的,只有当睡眠的时间结束,才会重新进入到就绪状态,而就绪状态进入到运行状态,是由系统控制的,我们不可能精准的去干涉它,所以如果调用Thread.sleep(1000)使得线程睡眠1秒,可能结果会大于1秒。

2、线程让步—yield:
  该方法和sleep方法类似,也是Thread类提供的一个静态方法,可以让正在执行的线程暂停,但是不会进入阻塞状态,而是直接进入就绪状态。相当于只是将当前线程暂停一下,然后重新进入就绪的线程池中,让线程调度器重新调度一次。也会出现某个线程调用yield方法后暂停,但之后调度器又将其调度出来重新进入到运行状态。

public class SynTest {
    public static void main(String[] args) {
        yieldDemo ms = new yieldDemo();
        Thread t1 = new Thread(ms,"张三吃完还剩");
        Thread t2 = new Thread(ms,"李四吃完还剩");
        Thread t3 = new Thread(ms,"王五吃完还剩");
        t1.start();
        t2.start();
        t3.start();
    }
}
class yieldDemo implements Runnable{
    int count = 20;
    public void run() {
        while (true) {
                if(count>0){
                    System.out.println(Thread.currentThread().getName() + count-- + "个瓜");
                    if(count % 2 == 0){
                        Thread.yield();                  //线程让步
                    }
            }
        }
    }
}

sleep和yield的区别:

      ①、sleep方法声明抛出InterruptedException,调用该方法需要捕获该异常。yield没有声明异常,也无需捕获。
      ②、sleep方法暂停当前线程后,会进入阻塞状态,只有当睡眠时间到了,才会转入就绪状态。而yield方法调用后 ,是直接进入就绪状态。

3、线程合并—join:

      当B线程执行到了A线程的.join()方法时,B线程就会等待,等A线程都执行完毕,B线程才会执行。
      join可以用来临时加入线程执行。以下为代码演示:

public static void main(String[] args) throws InterruptedException {    
        yieldDemo ms = new yieldDemo();
        Thread t1 = new Thread(ms,"张三吃完还剩");
        Thread t2 = new Thread(ms,"李四吃完还剩");
        Thread t3 = new Thread(ms,"王五吃完还剩");
        t1.start();
        t1.join();
        
        t2.start();
        t3.start();
        System.out.println( "主线程");
    }

4、停止线程:

      原stop方法因有缺陷已经停用了,那么现在改如何停止线程?现在分享一种,就是让run方法结束。
      开启多线程运行,运行的代码通常是循环结构,只要控制住循环,就可以让run方法结束,也就是线程结束。

具体代码如下:

 1 public class StopThread {
 2 
 3     public static void main(String[] args) {
 4         int num = 0;
 5         StopTh st = new StopTh();
 6         Thread t1 = new Thread(st);
 7         Thread t2 = new Thread(st);
 8         t1.start();
 9         t2.start();
10         //设置主线程执行50次,执行结束之后停止线程
11         while (true) {
12             if(num++ == 50){                        
13                 st.flagChange();
14                 break;
15             }
16             System.out.println(Thread.currentThread().getName() + "..." + num);
17         }
18     }
19 }
20 
21 class StopTh implements Runnable{
22 
23     private boolean flag = true;
24     public void run() {
25         while(flag){
26             System.out.println(Thread.currentThread().getName() + "stop run" );
27         }
28     }
29     public void flagChange(){
30         flag = false;
31     }
32 }

特殊情况:当线程处于了冻结状态,就不会读取到标记,也就不会结束。当没有指定方法让冻结的线程回复到运行状态时,我们需要对冻结状态进行清除,也就是强制让线程恢复到运行状态中来,这样可就可以操作标记让线程结束。
  Thread类提供该方法: interrupt();(如果线程在调用Object类的wait()、wait(long)、wait(long,int)方法,或者该类的join()、join(long)、join(long、int)、sleep(long)或sleep(long、int)方法过程中受阻,则其中断状态将被清除,还将收到一个InterruptedException。)
5、设置优先级:

      每个线程执行时都有一个优先级的属性,优先级高的线程可以获得较多的执行机会,而优先级低的线程则获得较少的执行机会。与线程休眠类似,线程的优先级仍然无法保障线程的执行次序。只不过,优先级高的线程获取CPU资源的概率较大,优先级低的也并非没机会执行。
  Thread类中提供了优先级的三个常量,代码如下:

MAX_PRIORITY   =10

MIN_PRIORITY   =1

NORM_PRIORITY   =5
-----------------------------------------------------
 ThreadDemo td = new ThreadDemo();
 Thread t1 = new Thread(td,"张三");
 t1.priority(9);            //设置优先级
 t1.start();              //设置完毕
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值