看一块关于给线程Thread加锁的代码产生的疑惑

看一块关于给线程Thread加锁的代码产生的疑惑

BLOCKED
  • 创建线程T1,T2调用start()方法,T1,T2状态均为RUNNABLE
  • 若T1获得锁,T1状态为RUNNABLE,T2状态变为BLOCKED
  • 等待T1执行完释放锁,T2获得锁,T2状态RUNNABLE

class BlockThread extends Thread {
    private String name;    //当前线程名称
    private Object lock;    //锁
    public BlockThread(Object lock,String name){
        this.lock = lock;
        this.name = name;
    }
    @Override
    public void run() {
        System.out.println("Thread "+name+" State is "+Thread.currentThread().getState());
        synchronized (lock) {
            System.out.println("Thread "+name+" hold the lock");
            try {
                System.out.println("Thread "+name+" State is "+Thread.currentThread().getState());
                Thread.sleep(1000 * 10);    //抢到锁的线程执行逻辑,这里用睡眠模拟
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Thread " + name + " release the lock");
        }
    }
}
public class Test{
    public static void main(String[] args) throws Exception{
        Object lock = new Object();//锁
        BlockThread t1 = new BlockThread(lock,"T1");
        BlockThread t2 = new BlockThread(lock,"T2");
        t1.start(); //线程 T1开始运行
        t2.start(); //线程 T2开始运行
        Thread.sleep(100);  //阻塞主线程,等待T1,T2抢锁
        System.out.println("Thread T1 State is " + t1.getState());  //获取T1线程状态
        System.out.println("Thread T2 State is " + t2.getState());  //获取T2线程状态
    }
}

输出结果 

Thread T1 State is RUNNABLE
Thread T1 hold the lock
Thread T1 State is RUNNABLE
Thread T2 State is RUNNABLE
Thread T1 State is TIMED_WAITING
Thread T2 State is BLOCKED
Thread T1 release the lock
Thread T2 hold the lock
Thread T2 State is RUNNABLE
Thread T2 release the lock

疑惑一:如何区分TIMED_WAITING和WAITING

        *Thread.sleep(long millis) 使当前线程暂停执行指定的时间。因为这个时间是已知的,所以状态是 TIMED_WAITING(它意味着线程正在等待,但有一个明确的时间限制)。

        *而 Object.wait() 方法会导致线程进入 WAITING 状态,因为它会使线程无限期地等待,直到它被通知或被中断。也有一个 Object.wait(long timeout) 方法,它会导致线程进入TIMED_WAITING 状态,因为它有一个时间限制。

所以,TIMED_WAITING 和 WAITING 的主要区别是,前者有一个明确的等待时间,而后者没有。当你调用 Thread.sleep(), 你明确地告诉线程等待指定的毫秒数,所以它进入 TIMED_WAITING 状态

疑惑二:因为看到Thread T2没有在T1结束后输出TIMED_WAITING,天真的怀疑是不是synchronized锁是否执行了1次后就没用了

T2是进入了与T1完全相同的synchronized块。synchronized块不是一次性的;它可以由任何线程多次进入,只要该线程拥有锁。在这种情况下,T1和T2都将轮流执行相同的synchronized块。

疑惑三:那为什么最后T2没有输出TIME_WAITING的State?

但在main方法中,只是在T1和T2启动后稍微暂停了一会儿(Thread.sleep(100))来检查并打印线程状态。

这时,T1可能还在睡眠或即将完成,并且T2可能刚刚开始它的synchronized块或即将开始。

为了确实看到T2的TIMED_WAITING状态,需要确保在T1释放锁之后,还有足够的时间让T2进入其synchronized块并开始睡眠。可以通过在主线程中加入更长的睡眠来实现这一点,

例如Thread.sleep(1000 * 11)

这将确保在打印状态之前,T1已经完成了它的synchronized块并且T2已经开始它的睡眠。 所以,是的,如果你想在主程序中看到T2的TIMED_WAITING状态,你需要让主程序等待与锁块中的sleep时间相同或更长的时间,然后再打印T2的状态。

主线程和你创建的其他线程(如T1和T2)都是并发运行的。它们可以交替运行,具体取决于操作系统的线程调度。 因此,你的主程序(或主线程)在执行Thread.sleep(100)时,T1和T2仍然在后台运行。当主线程在休眠时,T1和T2还在执行它们的任务

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值