Java线程控制

线程的生命周期

线程的生命周期:新建(NEW),就绪(Runnable),运行(Running),阻塞(Blocked),死亡(Dead)5种状态。

新建和就绪

当使用 new关键字创建一个线程时,线程处于新建状态。Java虚拟机为其分配内存。并初始化其成员变量的值。
当线程对象调用 start()方法后,线程处于就绪状态。Java虚拟机为其创建方法调用栈和程序计数器。
只能对处于新建状态的线程调用 start() 方法。否则会引发 IllegalThreadStateException。

运行和阻塞状态

如果处于就绪状态的线程获得CPU,开始执行run() 方法,则线程处于运行状态。
线程运行过程中会被中断, 目的是使其他线程获得执行机会。
失去处理资源的线程进入就绪状态, 获得处理资源的线程会由就绪进入运行状态。
调用 yield() 方法可以让运行状态进入就绪状态。

发生下面情况时:进入阻塞状态

  • 线程调用sleep()
  • 调用一个阻塞时IO方法, 在该方法返回之前,该线程会被阻塞
  • 获得一个同步监视器,该监视器正被其他线程所持有
  • 等待某个通知notify
  • 调用 suspend()挂起
    被阻塞后,其他线程获得执行的机会。
    上面被阻塞的线程, 下面情况时,会重新进入就绪状态:
  • sleep() 时间过了
  • 阻塞式IO已返回
  • 获得了同步监视器
  • 等待通知时, 其他线程发出来一个通知
  • 处于挂起状态的线程,调用了 resume()

线程死亡

线程会以以下三种方式结束,结束后处于死亡状态

  • run() 或 call()方法执行完
  • 抛出一个未捕获的Exception或 Error
  • 调用线程的 stop() 方法, 易导致死锁
    可以通过 isAlive() 方法判断是否死亡: 就绪,运行,阻塞时返回TRUE, 新建和死亡时返回false。
    处于死亡状态的线程无法再次运行。

控制线程

join线程

当在程序执行中调用其他线程的 join()方法时,调用线程会被阻塞,直到被join()方法加入的join线程执行完为止。

public class FirstThread extends Thread {

    public FirstThread(String name){
        super(name);
    }

    public void run(){
        for (int i = 0; i < 100; i++){
            System.out.println(getName()  + "  " + i);
        }
    }

    public static void main(String[] args) throws Exception{
        new FirstThread("新线程").start();
        
        for(int i = 0; i < 100; i++){
            if(i == 20){
                FirstThread firstThread = new FirstThread("join 线程");
                firstThread.start();
                firstThread.join();
            }
            System.out.println(Thread.currentThread().getName() + " " + i);

        }
    }
}
//Output
...
join 线程  96
join 线程  97
join 线程  98
join 线程  99
main 20
main 21
main 22
main 23
main 24
...

"join 线程"执行完后, 主线程才会继续执行。
join(long millis) 可以设置join线程的等待最长时间,如果该时间内还没有执行结束,则不再等待。

后台线程

后台线程 Daemon Thread, 也称为守护线程。
前台线程死亡时,后台线程会自动死亡。
调用线程对象的 setDaemon(true)设置为后台线程。
isDaemon() 可以判断

public class FirstThread extends Thread {
    public void run(){
        for (int i = 0; i < 1000; i++){
            System.out.println(getName()  + "  " + i);
        }
    }

    public static void main(String[] args){
        FirstThread firstThread = new FirstThread();
        firstThread.setDaemon(true);
        firstThread.start();

        for(int i = 0; i < 10; i++){
            System.out.println(Thread.currentThread().getName()  + "  " + i);
        }
    }
}
//Output
...
Thread-0  112
Thread-0  113
Thread-0  114
Thread-0  115
Thread-0  116

后台线程并没有执行完,前台退出后后台线程也结束了。
前台线程创建的子线程默认是前台线程, 后台线程创建的子线程,默认是后台线程

sleep()

sleep() 让线程暂停一段时间, 进入阻塞状态。
Thread.sleep(1000)
暂停1000 ms。

yield()

yield()是Thread类提供的一个静态方法。 让线程暂停,但不会进入阻塞状态,只是将线程转入就绪状态,
当某个线程调用yield时, 只有优先级大于等于当前线程的,处于就绪状态的线程执行。

可以通过 setPriority()设置优先级, 参数为 0- 10 之内的整数。

  • MAX_PRIORITY : 10
  • MIN_PRIORITY : 1
  • NORM_PRIORITY: 5
public class FirstThread extends Thread {

    public FirstThread(String name){
        super(name);
    }

    public void run(){
        for (int i = 0; i < 50; i++){
            System.out.println(getName()  + "  " + i);
            if(i == 20){
                Thread.yield();
            }
        }
    }

    public static void main(String[] args){
        FirstThread t1 = new FirstThread("HIGH");
        t1.setPriority(Thread.MAX_PRIORITY);
        t1.start();

        FirstThread t2 = new FirstThread("LOW");
        t2.setPriority(Thread.MIN_PRIORITY);
        t2.start();
	}
}
//Output
...
LOW  18
LOW  19
LOW  20
HIGH  21
HIGH  22
HIGH  23
HIGH  24
HIGH  25
HIGH  26
...
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值