JAVA基础 线程的状态转换,Thread status


在这里插入图片描述

sleep VS wait

sleep()方法(休眠)是线程类(Thread)的静态方法,调用此方法会让当前线程暂停执行指定的时间,将执行机会(CPU)让给其他线程,但是对象的锁依然保持,因此休眠时间结束后会自动恢复(线程回到就绪状态,请参考第66题中的线程状态转换图)。
.
wait()是Object类的方法,调用对象的wait()方法导致当前线程放弃对象的锁(线程暂停执行),进入对象的等待池(wait pool),只有调用对象的notify()方法(或notifyAll()方法)时才能唤醒等待池中的线程进入等锁池(lock pool),如果线程重新获得对象的锁就可以进入就绪状态。

请说出与线程同步以及线程调度相关的方法。

wait():使一个线程处于等待(阻塞)状态,并且释放所持有的对象的锁;
.
sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要处理InterruptedException异常;
.
notify():唤醒一个处于等待状态的线程,当然在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且与优先级无关;
.
notityAll():唤醒所有处于等待状态的线程,该方法并不是将对象的锁给所有线程,而是让它们竞争,只有获得锁的线程才能进入就绪状态。
.
Thread.yield 让出CPU,进入就绪状态
.
t1.join() 阻塞宿主线程

1.join()方法

public class ThreadJoinTest {
	/**
	 *  Join(): 又叫做:等待线程死亡(Waits for this thread to die.)
	 * 
     * 测试case说明:
     * join()方法只会使宿主线程(或者说调用t.join()的线程)进入等待池并等待t线程执行完毕后才会被唤醒。并不影响同一时刻处在运行状态的其他线程。
     * join源码中,只会调用wait方法,并没有在结束时调用notify,这是因为线程在die的时候会自动调用自身的notifyAll方法,来释放所有的资源和锁。
     * 需要注意,如果ta线程未被启动或者终止,则isAlive方法返回false,及join方法无效
     * 
     */
    public static void main(String[] args) throws InterruptedException {
        ThreadTestP1 ta = new ThreadTestP1("A");

        ThreadTestP1 tb = new ThreadTestP1("B");

        ThreadTestP1 tc = new ThreadTestP1("C");

        //启动线程
        ta.start();

        System.out.println("-----------AAA------------------------------------");

        tb.start();
        System.out.println("-----------BBB-----------------------------------");

        ta.join();

        tc.start();

//        Thread.sleep(3000);
    }
}


-----------------------------------------------------------------

@Slf4j
@Data
@AllArgsConstructor
public class ThreadTestP1 extends Thread {

    private String tName;

    @SneakyThrows
    @Override
    public void run() {
        for (int i = 1; i <= 5; i++) {
            Thread.sleep(100);
           log.info("ThreadTestP1 name is {}, iter:[{}]",tName,i);
        }
    }
}

-----------------------------源码------------------------------------------
    /**
    * millis 设置超时时间
    * 关键点: synchronized, 
    *    join方法的本质调用的是Object中的wait方法实现线程的阻塞。
    * 	 但是我们需要知道的是,调用wait方法必须要获取锁,所以join方法是被synchronized修饰的
    *     synchronized修饰在方法层面相当于synchronized(this),this就是Thread本身的实例
    */
    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");
        }

		// 判断是否携带阻塞的超时时间,等于0表示没有设置超时时间
        if (millis == 0) {
            while (isAlive()) {  
                wait(0);       // ---> 无限等待直到线程t结束
            }
        } else {
            while (isAlive()) {
                long delay = millis - now;
                if (delay <= 0) {
                    break;
                }
                wait(delay); // ---> 等待指定的时间后,宿主线程阻塞结束
                now = System.currentTimeMillis() - base;
            }
        }
    }

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值