java线程的6种状态以及相互转换

线程如何创建

创建线程有三种方式:继承Thread类;无返回值的Runnable;有返回值的Callable

示例如下

package com.rcl.platform.demo;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class CreateThread {

    public static class TestThread extends Thread {
        @Override
        public void run() {
            System.out.println("--继承thread--");
        }
    }

    public static class TestRunnable implements Runnable {

        @Override
        public void run() {
            System.out.println("--runnable没有返回值--");
        }

    }

    public static class TestCallable implements Callable<String> {

        @Override
        public String call() throws Exception {
            System.out.println("--callable有返回值--");
            return "test-callable";
        }

    }
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        Thread thread = new Thread(new TestThread());
        thread.start();

        thread = new Thread(new TestRunnable());
        thread.start();

        FutureTask<String> ft = new FutureTask<>(new TestCallable());
        thread = new Thread(ft);
        thread.start();

        System.out.println(ft.get());

    }
}

执行结果

--继承thread--
--runnable没有返回值--
--callable有返回值--
test-callable

线程相关的基础方法

wait:获取锁对象monitor的线程执行wait方法,将会释放对monitor的控制权,其他线程可以获取到锁对象的monitor,执行notify唤醒wait线程

notify/notifyall:获取到monitor,唤醒曾经获取到monitor执行wait正在处于等待的线程(线程状态为WAITING,TIMED_WAITING)

sleep:线程休眠

yield:yield方法的作用是暂停当前线程,以便其他线程有机会执行,不过不能指定暂停的时间,并且也不能保证当前线程马上停止。yield方法只是将Running状态转变为Runnable状态(不能完全保证,最好少用)

join:join方法的作用是父线程等待子线程执行完成后再执行,换句话说就是将异步执行的线程合并为同步的线程,如:如果在mian线程执行的过程中执行t1.join方法,那么将转而执行t1线程,t1线程执行完毕后执行mian线程

package com.rcl.platform.demo;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

public class JoinTest {

    public static class TestThread extends Thread {
        @Override
        public void run() {
            for(int i=0; i<10; i++){
                System.out.println("第" + i + "次执行");
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void main(String[] args) throws InterruptedException, ExecutionException {

        TestThread thread = new TestThread();
        thread.start();

        thread.join();
        System.out.println("等待thread执行完毕后main线程结束");
    }
}

执行结果

第0次执行
第1次执行
第2次执行
第3次执行
第4次执行
第5次执行
第6次执行
第7次执行
第8次执行
第9次执行
等待thread执行完毕后main线程结束

interrupt:他的作用是“停止”当前线程的运行,为什么加上一个引号,它只在特殊情况下有用,像线程调用了wait,sleep,join等可中断的阻塞方法 后,调用interrupt就会抛出InterruptedException异常。其实它称为协作停止。调用了这个方法后线程除了特殊情况外别的时候并不会停止,它发送一个停止请求,并且由线程记录下来(实际上就是有一个为bool的变量,当为true时就表示有停止线程运行请求)。所以说线程真正的停止需要我们自己去检查是否有停止线程的请求,当有线程停止请求时停用当前线程。和他配套是使用的有

public static boolean interrupted()

public boolean isInterrupted()

package com.rcl.platform.demo;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

public class JoinTest {

    public static class TestThread extends Thread {
        @Override
        public void run() {
            for(int i=0; i<1000000000; i++){
                System.out.println("TestThread第" + i + "次执行");
                if(Thread.interrupted()){
                    return;
                }
        }
        }
    }

    public static class TestThreadSleep extends Thread {
        @Override
        public void run() {
            for(int i=0; i<10; i++){
                System.out.println("TestThreadSleep第" + i + "次执行");
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if(Thread.interrupted()){
                    return;
                }
        }
        }
    }

    public static void main(String[] args) throws InterruptedException, ExecutionException {

        TestThread thread = new TestThread();
        thread.start();
        thread.interrupt();

        TestThreadSleep threadSleep = new TestThreadSleep();
        threadSleep.start();
        threadSleep.interrupt();
    }
}

执行结果

TestThread第0次执行
TestThreadSleep第0次执行
java.lang.InterruptedException: sleep interruptedTestThreadSleep第1次执行

    at java.lang.Thread.sleep(Native Method)
    at java.lang.Thread.sleep(Thread.java:340)
    at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386)
    at com.rcl.platform.demo.JoinTest$TestThreadSleep.run(JoinTest.java:27)
TestThreadSleep第2次执行
TestThreadSleep第3次执行
TestThreadSleep第4次执行
TestThreadSleep第5次执行
TestThreadSleep第6次执行
TestThreadSleep第7次执行
TestThreadSleep第8次执行
TestThreadSleep第9次执行

线程状态

1、java线程有6中状态,分别为NEW,RUNNABLE,BLOCKED,WAITING,TIMED_WAITING,TERMINATED详解java.lang.Thread$State枚举类

2、线程初始化为NEW状态,该状态表示还未调用start方法

3、执行线程调用start方法,线程状态转换为RUNNABLE(包括竞争到CPU时间真正意义的执行和没有竞争到CPU时间等待下一个CPU时间的状态)

4、BLOCKED状态为锁竞争,没有竞争到锁为BLOCKED,等待拥有锁的线程释放锁,进入RUNNABLE状态

5、WAITING状态为竞争到锁,执行wait方法,又释放锁,本线程进入WAITING,等待其他线程唤醒notify,notifyall,如果不唤醒,将一直处于WAITING状态

6、TIMED_WAITING为执行sleep join或者有时限的等待

7、线程执行完毕,线程处于TERMINATED状态

线程状态变化

package com.rcl.platform.demo;

import java.util.concurrent.TimeUnit;

public class ThreadState {
    public static void main( String[] args ) throws InterruptedException {
        System.out.println("-------------NEW-------------");
        Thread thread = new Thread();
        System.out.println(thread.getState() + ":" + (thread.getState() == Thread.State.NEW));

        System.out.println("-------------分割线-------------");

        System.out.println("-------------RUNNABLE、TERMINATED-------------");
        thread = new Thread(new Runnable() {
            public void run() {
                System.out.println(Thread.currentThread().getState() + ":" + (Thread.currentThread().getState() == Thread.State.RUNNABLE));
            }
        });
        thread.start();

        TimeUnit.SECONDS.sleep(1);
        System.out.println(thread.getState() + ":" + (thread.getState() == Thread.State.TERMINATED));

        System.out.println("-------------分割线-------------");

        System.out.println("-------------RUNNABLE、TIMED_WAITING-------------");
        thread = new Thread(new Runnable() {
            public void run() {
                System.out.println(Thread.currentThread().getState() + ":" + (Thread.currentThread().getState() == Thread.State.RUNNABLE));
                System.out.println("sleep 进入 TIMED_WAITING");
                try {
                    TimeUnit.SECONDS.sleep(2);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        thread.start();

        TimeUnit.SECONDS.sleep(1);
        System.out.println(thread.getState() );
        TimeUnit.SECONDS.sleep(2);

        System.out.println("-------------分割线-------------");

        System.out.println("-------------RUNNABLE、TIMED_WAITING-------------");
        final Thread mainThread = Thread.currentThread();
        thread = new Thread(new Runnable() {
            public void run() {
                System.out.println(Thread.currentThread().getState() + ":" + (Thread.currentThread().getState() == Thread.State.RUNNABLE));
                try {
                    System.out.println("join 进入 TIMED_WAITING");
                    System.out.println("mainThread: " + mainThread.getState());
                    TimeUnit.SECONDS.timedJoin(mainThread, 2);//先执行mainthread
                    System.out.println("mainThread: " + mainThread.getState());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        thread.start();
        TimeUnit.SECONDS.sleep(1);
        System.out.println("testThread: " + thread.getState() );

        System.out.println("-------------分割线-------------");

        System.out.println("-------------RUNNABLE、WAITING-------------");
        Object lock = new Object();
        final Thread mainThread1 = Thread.currentThread();
        thread = new Thread(new Runnable() {
            public void run() {
                synchronized (lock) {
                    try {
                        System.out.println("wait 进入 WAITING");
                        lock.wait();
                        System.out.println("mainThread1: " + mainThread1.getState() );
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                }
            }
        });
        thread.start();
        TimeUnit.SECONDS.sleep(1);
        System.out.println("testThread: " + thread.getState() );
        synchronized (lock) {
            lock.notifyAll();
        }
        TimeUnit.SECONDS.sleep(1);

        System.out.println("-------------分割线-------------");
        Thread thread1 = new Thread(new Runnable() {
            public void run() {
                synchronized (lock) {
                    try {
                        TimeUnit.SECONDS.sleep(2);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                }
            }
        });
        thread1.start();
        Thread thread2 = new Thread(new Runnable() {
            public void run() {
                synchronized (lock) {

                }
            }
        });
        thread2.start();
        TimeUnit.SECONDS.sleep(1);
        System.out.println("thread2: " + thread2.getState() );
    }
}

执行结果

-------------NEW-------------
NEW:true
-------------分割线-------------
-------------RUNNABLE、TERMINATED-------------
RUNNABLE:true
TERMINATED:true
-------------分割线-------------
-------------RUNNABLE、TIMED_WAITING-------------
RUNNABLE:true
sleep 进入 TIMED_WAITING
TIMED_WAITING
-------------分割线-------------
-------------RUNNABLE、TIMED_WAITING-------------
RUNNABLE:true
join 进入 TIMED_WAITING
mainThread: TIMED_WAITING
testThread: TIMED_WAITING
-------------分割线-------------
-------------RUNNABLE、WAITING-------------
wait 进入 WAITING
mainThread: TIMED_WAITING
testThread: WAITING
mainThread1: TIMED_WAITING
-------------分割线-------------
thread2: BLOCKED

欢迎加入学习交流群569772982,大家一起学习交流。

 
时间: 2024-11-09 07:37:01

java线程的6种状态以及相互转换的相关文章

java 线程的几种状态(转载)

java thread的运行周期中, 有几种状态, 在 java.lang.Thread.State 中有详细定义和说明: NEW 状态是指线程刚创建, 尚未启动 RUNNABLE 状态是线程正在正常运行中, 当然可能会有某种耗时计算/IO等待的操作/CPU时间片切换等, 这个状态下发生的等待一般是其他系统资源, 而不是锁, Sleep等 BLOCKED  这个状态下, 是在多个线程有同步操作的场景, 比如正在等待另一个线程的synchronized 块的执行释放, 或者可重入的 synchro

java 线程的几种状态

java thread的运行周期中, 有几种状态, 在 java.lang.Thread.State 中有详细定义和说明: NEW 状态是指线程刚创建, 尚未启动 RUNNABLE 状态是线程正在正常运行中, 当然可能会有某种耗时计算/IO等待的操作/CPU时间片切换等, 这个状态下发生的等待一般是其他系统资源, 而不是锁, Sleep等 BLOCKED  这个状态下, 是在多个线程有同步操作的场景, 比如正在等待另一个线程的synchronized 块的执行释放, 或者可重入的 synchro

【转】java 线程的几种状态

java thread的运行周期中, 有几种状态, 在 java.lang.Thread.State 中有详细定义和说明: NEW 状态是指线程刚创建, 尚未启动 RUNNABLE 状态是线程正在正常运行中, 当然可能会有某种耗时计算/IO等待的操作/CPU时间片切换等, 这个状态下发生的等待一般是其他系统资源, 而不是锁, Sleep等 BLOCKED  这个状态下, 是在多个线程有同步操作的场景, 比如正在等待另一个线程的synchronized 块的执行释放, 或者可重入的 synchro

Java线程的几种状态

一. 线程状态类型1. 新建状态(New):新创建了一个线程对象.2. 就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法.该状态的线程位于可运行线程池中,变得可运行,等待获取CPU的使用权.3. 运行状态(Running):就绪状态的线程获取了CPU,执行程序代码.4. 阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行.直到线程进入就绪状态,才有机会转到运行状态.阻塞的情况分三种:(一).等待阻塞:运行的线程执行wait(

在java中怎样实现多线程?线程的4种状态

一.在java中怎样实现多线程? extends Thread implement Runnable 方法一:继承 Thread 类,覆盖方法 run(),我们在创建的 Thread 类的子类中重写 run() ,加入线程所要执行的代码即可. 下面是一个例子: public class MyThread extends Thread { int count= 1, number; public MyThread(int num) { number = num; System.out.printl

Java线程基础知识(状态、共享与协作)

1.基础概念 CPU核心数和线程数的关系 核心数:线程数=1:1 ;使用了超线程技术后---> 1:2 CPU时间片轮转机制 又称RR调度,会导致上下文切换 什么是进程和线程 进程:程序运行资源分配的最小单位,进程内部有多个线程,会共享这个进程的资源 线程:CPU调度的最小单位,必须依赖进程而存在. 澄清并行和并发 并行:同一时刻,可以同时处理事情的能力 并发:与单位时间相关,在单位时间内可以处理事情的能力 高并发编程的意义.好处和注意事项 好处:充分利用cpu的资源.加快用户响应的时间,程序模

Java学习之==&gt;Java线程生命周期与状态切换

一.Java线程生命周期与状态切换 这些状态的描述可以总结成下图: NEW 一个刚创建但尚未启动的Java线程实例就是处于 NEW 状态 public class App { public static void main(String[] args) { Thread thread = new Thread(); Thread.State state = thread.getState(); System.out.println(state); } } // 输出结果 NEW RUNNABLE

Hibernate 入门 04 - Hibernate中Java对象的三种状态

目录:(后续不断更新...) Hibernate 入门 01 - 框架技术 (介绍Hibernate框架的发展由来) Hibernate 入门 02 - Hibernate介绍及其环境搭建 Hibernate 入门 03 - 使用Hibernate完成持久化操作 Hibernate 入门 04 - Hibernate中Java对象的三种状态 ▁▃▅ Hibernate中Java对象的三种状态▅▃▁ 1. Java对象的三种状态 当应用通过调用Hibernate API与框架发生交互时,需要从持久

【线程系列二】线程的五种状态

线程有5种状态,分别是新建.受阻塞.运行.死亡.休眠.等待. 在api中的解释如下图1所示 图1 图2 解释一下上述图2的过程. 1.new一个线程对象,该对象的状态为"新建状态". 2.执行start(),如果cpu现在空闲,则切换到运行状态,否则切换到阻塞状态. 3.线程执行sleep(),切换到休眠状态,在休眠时间到期后,自动切换到(运行或阻塞) 4.执行wait(),切换到等待状态,如果不执行notifiy(),则一直处于等待状态. 5.在线程中的run()执行完毕后,线程切换