多线程编程(三)——线程的状态

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/swadian2008/article/details/99088366

目录

一、线程状态:NEW、RUNNABLE、TERMINATED

二、线程状态:TIME_WATING(限时等待)

三、线程状态:BLOCKED(等待锁)

四、线程状态:WAITING(条件等待状态)

五、isAlive()方法


线程运行状态图解:

一、线程状态:NEW、RUNNABLE、TERMINATED

NEW:新建状态,线程中的任务代码还没有开始执行,如new Mythread(),此时处于新建状态,新建状态的线程没有执行start()方法

RUNNABLE:就绪状态,即可运行状态;当线程调用了start()方法,当前线程进入可运行状态,可运行状态并不立即执行run()方法,它还需要于其他线程争夺CPU的使用权限。

RUNNING:运行状态,获取到CPU使用权,执行run()方法;线程只能从可运行状态进入运行状态

TERMINATED:停止状态,线程执行完或因异常退出run()方法,该线程的生命周期结束

测试代码:

public class Mythread extends Thread {

    public Mythread() {
        System.out.println("线程名称:" + currentThread().getName()
                + ",构造方法中的状态:" + Thread.currentThread().getState()
                + ",线程是否存活:" + Thread.currentThread().isAlive());
    }

    @Override
    public void run() {
        System.out.println("线程名称:" + currentThread().getName() 
                + ",Run方法中的状态:" + Thread.currentThread().getState() 
                + ",线程是否存活:" + Thread.currentThread().isAlive());
    }

    public static void main(String[] args) throws InterruptedException {
        Mythread mythread = new Mythread();
        System.out.println("线程名称:" + mythread.getName() 
                + ",实例化对象后的状态:" + mythread.getState() 
                + ",线程是否存活:" + mythread.isAlive());
        Thread.sleep(1000);
        mythread.start();
        Thread.sleep(1000);
        System.out.println("线程名称:" + mythread.getName() 
                + ",线程运行结束后状态:" + mythread.getState() 
                + ",线程是否存活:" + mythread.isAlive());
    }
}

执行结果如下图:

二、线程状态:TIME_WATING(限时等待)

TIME_WATING:限时等待状态;线程执行了诸如Thread.sleep()或带有时间设定的Thread.join()、Object.wait()等方法时的等待状态,超过设定的等待时间,等待线程会自动唤醒,进入阻塞状态(Blocked)或者可运行状态(RUNNABLE)。

测试代码:

public class Mythread extends Thread {

    @Override
    public void run() {
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Mythread mythread = new Mythread();
        mythread.start();
        Thread.sleep(1000);
        // 打印下边语句的时候,线程还在睡眠当中
        System.out.println("线程名称:" + mythread.getName()
                + ",线程运行结束后状态:" + mythread.getState()
                + ",线程是否存活:" + mythread.isAlive());
    }
}

执行结果:

三、线程状态:BLOCKED(等待锁)

BLOCKED:阻塞状态,线程获取锁失败,会加入线程等待锁的同步阻塞队列,进入阻塞状态。该阻塞线程在获取锁后,会进入可运行状态(RUNNABLE),这里需要记住,线程是不能直接由非就绪状态进入运行状态的

1、创建带同步方法的MyService类:

public class MyService {

    public synchronized void serviceMethod() {
        try {
            System.out.println(Thread.currentThread().getName()+":执行serviceMethod方法中...");
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

2、创建线程A和线程B:

线程A:

public class MyThreadA extends Thread {

    private MyService myService;

    public MyThreadA(MyService myService){
        super();
        this.myService = myService;
    }

    @Override
    public void run() {
        myService.serviceMethod();
    }

}

线程B:

public class MyThreadB extends Thread {

    private MyService myService;

    public MyThreadB(MyService myService){
        super();
        this.myService = myService;
    }

    @Override
    public void run() {
        myService.serviceMethod();
    }

}

3、执行方法:

public static void main(String[] args) throws InterruptedException {
        MyService myService = new MyService();
        MyThreadA mythreadA = new MyThreadA(myService);
        mythreadA.setName("线程A");
        mythreadA.start();
        MyThreadB mythreadB = new MyThreadB(myService);
        mythreadB.setName("线程B");
        mythreadB.start();
        // 打印线程B的状态
        System.out.println("线程名称:" + mythreadB.getName()
                + ",线程运行状态:" + mythreadB.getState()
                + ",线程是否存活:" + mythreadB.isAlive());
    }

执行结果:

注:此处运行是处于就绪状态(RUNNABLE),sleep()方法不会释放锁,在只有一个对象锁的情况下,线程B是不会拿到锁的,所以这个状态应该是阻塞状态。

四、线程状态:WAITING(条件等待状态)

WAITING:又叫条件等待状态,当线程的运行条件不满足时,通过锁的条件等待机制(调用锁对象的wait()或显示锁条件对象的await()方法)让线程进入等待状态(WAITING)。处于等待状态的线程将不会被cpu执行,除非线程的运行条件得到满足后,其可被其他线程唤醒,进入阻塞状态(Blocked)。调用不带超时的Thread.join()方法也会进入等待状态。

1、创建锁对象:

注:一般情况下,不建议用String作为锁,在此为方便只作示例

因为在JVM中具有String常量池(如果两个String具有相同的值,那么他们的地址是相同的,都保存在这个常量池中)。当以String作为锁的时候,如果值相同则,那么线程持有相同的锁。这样就造成了另外一个线程不能执行。

public class MyLock {
    public static final String lock = "lock";
}

2、创建线程类和执行main()方法:

public class MyThread extends Thread {

    @Override
    public void run() {
        synchronized (MyLock.lock){
            try {
                MyLock.lock.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        MyThread myThread = new MyThread();
        myThread.start();
        Thread.sleep(1000);
        System.out.println("线程名称:" + myThread.getName()
                + ",线程运行状态:" + myThread.getState()
                + ",线程是否存活:" + myThread.isAlive());
    }
}

执行结果:

五、isAlive()方法

isAlive()方法是测试线程是否处于活动状态。从以上线程运行状况和结果可以得知,只有当线程在新建(NEW)和销毁(TERMINATED)状态时,线程的存活状态为false,其他时候线程始终处于活动状态。

猜你喜欢

转载自blog.csdn.net/swadian2008/article/details/99088366