线程状态转换

线程状态的转换

一、线程状态

thread
新状态:创建线程对象。未执行start()方法。
就绪:已经执行start()方法,具有运行资格,但是并不是马上运行,何时运行需要系统的调度。
运行:线程获得CPU资源,处于运行状态。
阻塞:线程有资格运行,但是他的运行需要条件,当条件触发时,可以装换为运行状态。
死亡:run()执行完,可以认为死去。线程死亡后,不能再次复活。

二、阻止正在执行的线程

  1. join()
    对于join()可能会让很多人困惑,比如说对于t.join()到底是怎么样运行的。对于线程t到底会有什么样的影响。
    先看Jdk对join()的介绍:
    public final void join(long millis)
    throws InterruptedException
    Waits at most millis milliseconds for this thread to die. A timeout of 0 means to wait forever.
    查看源码:
    public final synchronized void join(long millis)
    throws InterruptedException {
        long base = System.currentTimeMillis();
        long now = 0;

        if (millis < 0) {
            throw new IllegalArgumentException("timeout value is negative");
        }

        if (millis == 0) {
            while (isAlive()) {
                wait(0);
            }
        } else {
            while (isAlive()) {
                long delay = millis - now;
                if (delay <= 0) {
                    break;
                }
                wait(delay);
                now = System.currentTimeMillis() - base;
            }
        }
    }

从源码可以看出join方法基于wait方法实现。
wait()是Object的方法
查看Jdk对wait方法的介绍:
public final void wait()
throws InterruptedException
Causes the current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object.
wait方法让当前线程等待。由此可以看出t.join()是让当前执行这个方法的线程等待,如果是在main方法中,则main线程需要等待t线程执行完,才能执行。可以执行join方法是将当前线程加到t线程的尾部。
例子:

public class MyThread extends Thread{

    @Override
    public void run(){
        for (int i = 0;i < 5;i++) {
            System.out.println(Thread.currentThread().getName() + "-" + i);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

对于测试程序:

public class Test {

    public static void main(String[] args) {

        MyThread myThreadA = new MyThread();
        MyThread myThreadB = new MyThread();
        myThreadA.setName("A");
        myThreadB.setName("B");
        myThreadA.start();
        //myThreadB.start();
        try {
            myThreadA.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("main over");
    }
}

执行结果为:
A-0
A-1
A-2
A-3
A-4
main over
可以看出main在myThreadA执行完之后才继续执行。
2. Thread.sleep()
Thread.sleep(long millis)和Thread.sleep(long millis, int nanos)静态方法强制当前正在执行的线程休眠(暂停执行),以“减慢线程”。当线程睡眠时,它入睡在某个地方,在苏醒之前不会返回到可运行状态。当睡眠时间到期,则返回到可运行状态。
3. yield()
查看JDK介绍:
A hint to the scheduler that the current thread is willing to yield its current use of a processor. The scheduler is free to ignore this hint.
即yield的作用是释放当前线程所占用的资源,即让当前正在执行的程序从运行状态转为可执行状态。而当前CPU的资源由JVM自动调度给其他线程。
JVM调度的机制是基于优先级的抢占调度机制,当前运行的线程优先级将大于或等于线程池中任何线程的优先级。但这仅仅是大多数情况。
yield的暂停时间并不确定,可能会立即再次拥有CPU资源继续执行。
JVM调度的机制是基于优先级的抢占调度机制,当前运行的线程优先级将大于或等于线程池中任何线程的优先级。
但这仅仅是大多数情况。yield的暂停时间并不确定,可能会立即再次拥有CPU资源继续执行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值