JAVA线程状态

线程状态 意义
NEW 线程的初始状态,未被start()
RUNNABLE 线程被调用start后,无论还有没有进入Runnable接口的逻辑,都是runnable状态
BLOCKED 线程阻塞在某个锁上,等抢到锁。你可以想象处于这种状态的线程就像在门外拍门不停想要进入的人一样
WAITING 线程执行了sleep或者锁的wait后,处于一种假死状态,不会做任何事,直到被notify唤醒
TIMED_WAITING 被执行了有时间的wait后的状态,醒过来后如果还是拿不到锁就会转到BLOCKED状态,拿到了就是RUNNABLE
TERMINATED 执行完了Runnable逻辑,GG思密达

NEW

 @Test
    public void newState() {
        Thread thread = new Thread();
        System.out.println(thread.getState());//NEW
    }

RUNNABLE

    @Test
    public void runnableState() {
        new Thread(() -> {
            System.out.println("current thread state when doing sth : "
                       + Thread.currentThread().getState());//RUNNABLE
        }).start();
    }

BLOCKED

    @Test
    public void BlockedState() throws InterruptedException {
        Object lock = new Object();
        //启动一个线程获取锁,然后假装很忙,再也不放手
        new Thread(() -> {
            synchronized (lock) {
                while (true) {
                }
            }
        }).start();

        Thread threadB = new Thread(() -> {
            synchronized (lock) {
                System.out.println("lock acquired!");
            }
        });
        threadB.start();//线程开始后,状态变成RUNNABLE
        TimeUnit.SECONDS.sleep(5L);//让主线程在这暂停5S,此时B线程已经开始执行,尝试去获取锁,当然是获取不到的
        System.out.println(threadB.getState());//BLOCKED
    }

WAITING和TIMED_WAITING

先构造一个资源对象,内部有一个锁,调节线程对该资源对象的争夺

private class ValuableResource {
        private Object lock = new Object();

        /***
         * 线程获取到锁后,锁调用自己的wait方法向当前捏着自己的线程说,放开我,你去等着
         * 线程就会变成WAITING,注意这里的线程同时也会放弃锁的使用权
         * @throws InterruptedException
         */
        public void doSthWaiting() throws InterruptedException {
            synchronized (lock) {
                lock.wait();
            }

        }

        public void doSthTimedWaiting() throws InterruptedException {
            synchronized (lock) {
                lock.wait(3000L);
                while (true) {

                }
            }

        }
    }

WAITING

线程启动后,尝试去调用资源的doSthWaiting方法,此方法的逻辑是进来占用了锁的线程,会立即被锁告知请放开我,去门外等一等,所以这个线程最后会变成WAITING状态,注意这个wait方法是锁的方法,它的作用是告知当前占用了此锁的线程进入WAITING状态,并且放弃对此锁的占用

    @Test
    public void WaitedState() throws InterruptedException {
        Thread thread = new Thread(() -> {
            try {
                new ValuableResource().doSthWaiting();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });
        thread.start();
        TimeUnit.SECONDS.sleep(5L);//当前线程先等一下,让我们的目标线程充分运行

        System.out.println(thread.getState());//WAITING
    }

TIMED_WAITING

与上一种状态不同的是TIMED_WAITING会在时间到达后重新开始动作,你可以想象成这种状态是被锁告知了,嘿,你在门外等3S,时间到了,你该干嘛接着干嘛。

    @Test
    public void timedWaitingState() throws InterruptedException {
        Thread thread = new Thread(() -> {
            try {
                new ValuableResource().doSthTimedWaiting();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });
        thread.start();
        TimeUnit.SECONDS.sleep(2L);

        System.out.println(thread.getState());//TIMED_WAITING
        TimeUnit.SECONDS.sleep(2L);
        System.out.println(thread.getState());//RUNNABLE
    }

线程的sleep方法,会导致线程拥有的锁失去么?

线程A先获取到锁,然后睡觉
线程B尝试去获取锁,会处于BOLOCKED状态,证明了sleep并不会影响线程对锁的占用,该咋地还是咋的
其实也可以从方法的所有权去理解:
sleep()是Thread的静态方法,它管理的是当前线程,对于线程所占有的锁的情况,并不关心。
而wait()方法是锁本身的方法,告知当前占用自己的线程放弃自己,在门外等候。

    @Test
    public void sleepLock() {
        Object lock = new Object();
        Thread threadA = new Thread(() -> {
            synchronized (lock) {
                try {
                    TimeUnit.SECONDS.sleep(100000L);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        threadA.start();
        System.out.println("thread a start");
        Thread threadB = new Thread(() -> {
            synchronized (lock) {
                System.out.println("do stm");
            }
        });
        threadB.start();
        System.out.println("thread b start");
        System.out.println("thread b state: "+threadB.getState());   //BLOCKED
    }

join方法

join方法任然是属于线程的方法,所以他的效果是针对这个线程的。假设当调用线程A的join方法后,会将线程A的执行流程合并到当前线程中。意思就是会等线程A执行完了,当前线程才执行下去。其实看join的逻辑。
实现的方法还是wait()方法。将线程A本身作为一个锁,通过调用锁的wait()方法,使当前线程等待,直到线程A的isActive返回false,跳出循环后,当前线程继续执行

线程状态转换

image.png
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容