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

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状态是有权限获得对象锁的)。以此反复,从而形成了生产者消费者模式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值