标签 (空格分隔): 线程运行状态
线程的运行状态:
如下是是我编写的一个图, 大家可以作为参考:
1.new 一个 thread 子类也是创建了一个线程;
2. 创建完毕之后 start()----- 运行,
3. 然后从运行 -------sleep(time)---- 冻结 ----sleep(time) 时间到了, 恢复到运行;
4. 还有一种, 是线程运行的时候 ------wait 时间 ------ 到冻结状态 ------- 然后 notify() 唤醒 ----- 然后恢复到运行状态;
5. 消亡: 线程运行中 / 冻结: stop()/run 方法结束 --------- 消亡;
6. 临时状态: 当前状态等待 CPU 的执行权, 具备运行资格没有执行权,
7. 冻结: 放弃了执行资格;
8. 冻结状态 ----- 恢复 --- 临时状态 / 运行状态;
获取线程的对象和名称:
创建了对象之后, 都要匹配一个名称, 线程的名称都要定义在线程的事物里面:
- class Demo extends Thread{
- private String name;
- Demo(String name){
- this.name=name;
- }
- public void run(){// 将运行的代码放在 run 方法中
- for(int x=0;x<60;x++) {
- System.out.println(this.getName()+"demo run-----"+x);
- }
- }
- }
- class ThreadDemo{
- public static void main(String[] args){
- Demo d1= new Demo("one");// 创建好一个线程
- Demo d2= new Demo("two");
- d1.start();
- d2.start();
- for(int x=0;x<60;x++){
- System.out.println("helloworld!----"+x);
- }
- }
- }
原来线程都有自己默认的名称, Thread - 编号, 该编号从零开始;
2. 上述的名称是不是不太好看, 这里可以使用 set 方法来定义名称;
获取当前线程的名称:
static Thread currentThread(): 获取当前线程的对象;
getName(): 获取线程名称;
设置线程名称: setName 或者构造方法;
练习:
需求是一个简单的卖票程序, 多个窗口卖票, 1 号窗口在卖的时候, 2 号也在卖; 多个窗口同时卖票,
观察如下的程序:
- class Ticket extends Thread{
- private int tick=100;
- public void run(){
- while (true){
- if(tick>0) {
- System.out.println(Thread.currentThread().getName()+"sale:" + tick--);
- }
- }
- }
- }
- class TickDemo{
- public static void main(String[] args){
- Ticket t1=new Ticket();
- Ticket t2=new Ticket();
- Ticket t3=new Ticket();
- Ticket t4=new Ticket();
- t1.start();
- t2.start();
- t3.start();
- t4.start();
- }
- }
执行结果:
发现 100 个票, 卖出去了 400 张票; 每个对象里面包含了 100 张票;
如何实现: 100 张票 4 个窗口正常售卖呢?, 我们可以通过 static 定义变量来实现, 如下
- class Ticket extends Thread{
- private static int tick=100;
- public void run(){
- while (true){
- if(tick>0) {
- System.out.println(Thread.currentThread().getName()+"sale:" + tick--);
- }
- }
- }
- }
- class TickDemo{
- public static void main(String[] args){
- Ticket t1=new Ticket();
- Ticket t2=new Ticket();
- Ticket t3=new Ticket();
- Ticket t4=new Ticket();
- t1.start();
- t2.start();
- t3.start();
- t4.start();
- }
- }
执行通过;
但是一般我们不使用静态, 因为静态的生命周期比较长;
我们使用 Thread 创建线程不能实现了;
runable 接口:
Runable 接口应该由那些打算通过某一线程执行实例的类来实现, 类必须顶一个称为 run 的无参数方法, 设计该接口的目的就是提供一个公共协议, 例如, Thread 类实现了 Runable, 激活的意思是某个线程已经启动并且尚未停止;
- class Ticket implements Runnable{
- private static int tick=100;
- public void run(){
- while (true){
- if(tick>0) {
- System.out.println(Thread.currentThread().getName()+"sale:" + tick--);
- }
- }
- }
- }
- class TickDemo{
- public static void main(String[] args){
- // Ticket t1=new Ticket();
- // Ticket t2=new Ticket();
- // Ticket t3=new Ticket();
- // Ticket t4=new Ticket();
- // t1.start();
- // t2.start();
- // t3.start();
- // t4.start();
- Ticket t=new Ticket();
- Thread t1=new Thread();
- Thread t2=new Thread();
- Thread t3=new Thread();
- Thread t4=new Thread();
- t1.start();
- t2.start();
- t3.start();
- t4.start();
- }
- }
上述代码: 能否实现呢?
分析: t1 调用运行的 run() 是 Thread 里面的 run, 在这次代码里面未重写;
- package com.wangaling;
- class Ticket implements Runnable{
- private static int tick=100;
- public void run(){
- while (true){
- if(tick>0) {
- System.out.println(Thread.currentThread().getName()+"sale:" + tick--);
- }
- }
- }
- }
- class TickDemo{
- public static void main(String[] args){
- // Ticket t1=new Ticket();
- // Ticket t2=new Ticket();
- // Ticket t3=new Ticket();
- // Ticket t4=new Ticket();
- // t1.start();
- // t2.start();
- // t3.start();
- // t4.start();
- Ticket t=new Ticket();
- Thread t1=new Thread(t);
- Thread t2=new Thread(t);
- Thread t3=new Thread(t);
- Thread t4=new Thread(t);
- t1.start();
- t2.start();
- t3.start();
- t4.start();
- }
- }
执行结果:
上述代码可以正常实现售票的功能;
创建线程的第二种方式, 实现 runnable 接口
步骤 1:
1. 定义类实现 Runable 接口;
2. 覆盖 Runable 接口中的 run 方法: 将线程要运行的代码存在在 run 方法中
3. 通过 Thread 类建立线程对象
4. 将 Runable 接口的子类对象作为实际参数传递给 Thread 类的构造函数: 为什么要将 Runable 接口的子类的对象传递给 Thread 的构造函数, 因为, 自定义的 run 方法所属的对象是 Runable 接口的子类对象, 所以要让线程去指定指定对象的 run 方法, 就必须明确该 run 方法所属的对象;
5. 调用 Thread 类的 start 方法开启线程, 并调用 Runable 接口子类的 run 方法;
实现方式和继承方式有很么区别?
1. 实现方式好处: 避免了单继承的局限性, 在定义线程的时候建议是用实现方式, 可以避免单继承的实现性;
两种方式区别:
继承 Thread: 线程代码存放在 Thread 子类的 run 方法中;
实现 Runable, 线程代码存在接口的子类的 run 方法
来源: https://www.cnblogs.com/surewing/p/11427518.html