(14)Java多线程之线程状态

来源:互联网 发布:excel连接acsee数据库 编辑:程序博客网 时间:2024/05/05 22:43

  • 引言
  • 验证线程所处的状态
    • 1 验证New状态
      • 11 代码示例
      • 12代码解释
    • 2 验证Runable状态
      • 21 代码
      • 22代码解释
    • 3 验证terminated状态
      • 31 代码示例
      • 32 代码解释
    • 4 验证状态Timed_waiting
      • 41 代码示例
      • 42 代码解释
    • 5 验证Blocked状态
      • 51 代码示例
      • 52 代码解释
    • 6验证Waiting状态
      • 61 代码示例
      • 62代码解释
  • 从线程状态解释生产者消费者模式
    • 1 解释生产者消费者模式

1.引言

      在本篇博客中主要记录一下线程的状态,线程都存在哪一些状态?如何改变线程的状态。关于线程状态的信息都存储在State枚举类中。首先我们看一下线程的状态图:

这里写图片描述

现成的状态大致分为六种:

  • New:代表创建了线程对象,但是未执行start方法。
  • Runable:代表正在Java虚拟机中正在执行的线程。
  • blocked:代表线程受阻塞
  • Waiting:代表无限期的等待,知道其他线程给改线程发表唤醒命令
  • Timed Waiting:代表线程等待一定的时间
  • Terminated:代表线程已经退出

2. 验证线程所处的状态

现在我们就来使用 Demo来验证线程在一定情况下所处的状态

2.1 验证New状态

2.1.1 代码示例

  • 首先创建一个线程
public class MyThread extends Thread {    public void run() {    }}
  • main方法
public class App {    public static void main(String[] args) throws Exception {        MyThread td=new MyThread();        System.out.println(td.getState());    }}
  • 运行结果

这里写图片描述

2.1.2代码解释

  • 注意:当线程对象创建之后,但是没有执行start方法,此时线程的状态为:NEW

2.2 验证Runable状态

2.2.1 代码

  • 创建线程
public class MyThread extends Thread {    public void run() {        System.out.println(this.getState());    }}
  • main方法
public class App {    public static void main(String[] args) throws Exception {        MyThread td=new MyThread();        td.start();    }}
  • 运行结果

这里写图片描述

2.2.2代码解释

  • 当代码执行start方法之后,线程的状态变为Runable,注意:此时的线程并未执行完(也就是说线程在执行run方法),如果执行完,那么线程的状态就变成了terminated

2.3 验证terminated状态

2.3.1 代码示例

  • 线程代码
public class MyThread extends Thread {    public void run() {    }}
  • main函数
public class App {    public static void main(String[] args) throws Exception {        MyThread td=new MyThread();        td.start();        //保证td线程已经执行结束了        Thread.sleep(1000);        System.out.println(td.getState());    }}
  • 运行结果

这里写图片描述

2.3.2 代码解释

  • 当线程运行结束后:线程的状态修改为terminated

2.4 验证状态Timed_waiting

2.4.1 代码示例

  • 自定义线程
public class MyThread extends Thread {    public void run() {        try {            //让子线程睡2秒中。这里也可以是wait(timeout)方法,也可以是join(timeout)方法            Thread.sleep(2000);        } catch (InterruptedException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }}
  • main方法
public class App {    public static void main(String[] args) throws Exception {        MyThread td=new MyThread();        td.start();        //保证子线程在睡眠状态        Thread.sleep(1000);        System.out.println(td.getState());    }}
  • 运行结果

这里写图片描述

2.4.2 代码解释

  • 注意:我们不仅仅可以使用sleep方法让线程进入timed_waiting状态,也可以使用wait方法和join方法。
  • 再次注意:如果想要使用wait或者join方法进入timed_waiting,wait方法必须带参数,比如wait(2000),如果使用wait()方法(不带时间参数),那么将进入waiting状态

2.5 验证Blocked状态

2.5.1 代码示例

  • 创建service方法
public class service {    public static synchronized void printString() throws Exception {        System.out.println("线程等待5秒钟");        Thread.sleep(5000);     }}
  • 创建线程类
public class MyThread extends Thread {    private  Service service;    public MyThread(Service service){        this.service=service;    }    public void run() {        try {            service.printString();        } catch (Exception e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }}
  • main方法
public class App {    public static void main(String[] args) throws Exception {        Service service=new Service();        MyThread td1=new MyThread(service);        MyThread td2=new MyThread(service);        td1.start();        td2.start();        Thread.sleep(1000);        System.out.println(td2.getState());    }}
  • 运行结果

这里写图片描述

2.5.2 代码解释

  • td2线程正在等待获取对象锁,此时线程状态是Blocked

2.6验证Waiting状态

2.6.1 代码示例

  • 线程代码
public class MyThread extends Thread {    private  Object lock;    public MyThread(Object lock){        this.lock=lock;    }    public void run() {        synchronized (lock) {            try {                //注意这里                lock.wait();            } catch (InterruptedException e) {                e.printStackTrace();            }        }    }}
  • main方法
public class App {    public static void main(String[] args) throws Exception {        Object lock=new Object();        MyThread td=new MyThread(lock);        td.start();        Thread.sleep(1000);        System.out.println(td.getState());    }}
  • 运行结果

这里写图片描述

2.6.2代码解释

  • 注意状态Waiting和状态timed_waiting的区别
  • 执行wait方法使线程进入的是Waiting状态

3.从线程状态解释生产者/消费者模式

      通过上面的实例我们已经大致的了解了线程的状态都有哪几种,在什么情况下县线程会进入什么状态,接下来我们使用线程的状态来解释一下:生产者消费者模式(多生产多消费)

3.1 解释生产者/消费者模式

      首先我们从消费者说起,首先我们的产品的个数为0,消费者执行wait方法,然后消费者线程状态修改为waiting,这里我们可以看出waiting状态是没有权限争夺对象锁的,也就是一直处于等待状态,然后消费者唤醒生产者线程,生产者生产一个产品,然后唤醒消费者线程,注意:这里唤醒消费者线程假设我们使用的是notifyAll()方法,那么所有的消费者线程状态将变为Runable状态的准备阶段(假设我们将Runable状态分为准备阶段和运行阶段),如果某一个线程获取到了对象锁,那么该线程将会进入Runable的运行阶段,其他线程将会进入Blocked状态(也就是等待获得对象锁,注意:Blocked状态是有权限获得对象锁的)。以此反复,从而形成了生产者消费者模式。

1 0
原创粉丝点击