Java学习笔记(四十二)—— 线程的状态(Thread.State类)

Thread.State类

Thread.State线程状态。 线程可以处于以下状态之一:

  • NEW
    • 尚未启动的线程处于此状态。
  • RUNNABLE
    • 在Java虚拟机中执行的线程处于此状态。
  • BLOCKED
    • 被阻塞等待监视器锁定的线程处于此状态。
  • WAITING
    • 正在等待另一个线程执行特定动作的线程处于此状态。
  • TIMED_WAITING
    • 正在等待另一个线程执行动作达到指定等待时间的线程处于此状态。
  • TERMINATED
    • 已退出的线程处于此状态。

一个线程可以在给定时间点处于一个状态。 这些状态是不反映任何操作系统线程状态的虚拟机状态。

线程之间的通信
  1. 等待唤醒案例:线程之间的通信

    /*
        Object类中的方法:
            wait​(),导致当前线程等待,直到另一个线程调用该对象的 notify()方法或 notifyAll()方法。
            notify​(),唤醒正在等待对象监视器的单个线程。
    
    */
    	wait​()
    	Object obj=new Object();
        new Thread(){
            @Override
            public void run() {
                // 保证等待和唤醒的进程只能有一个执行
                synchronized (obj){
                    System.out.println("正在执行的线程");  // 执行顺序1
                    try {
                        obj.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    // 唤醒后执行的代码
                    System.out.println("执行唤醒后的线程"); // 执行顺序3
                }
            }
        }.start();
        new Thread(){
            @Override
            public void run() {
    
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (obj){
                    System.out.println("唤醒等待执行的线程"); // 执行顺序2
                    obj.notify(); // 随机唤醒等待的线程中的一个
                }
            }
        }.start();
    
  2. 进行TimeWaiting(计时等待)

    /*
        进行TimeWaiting(计时等待)的两种方式
            1、使用sleep(long m)方法,在毫米值结束之后,线程睡醒进入到Runnable/Blocked状态
            2、使用wait(long m)方法,在毫米值结束后,线程还没有被notify唤醒就会自动醒来,
                线程睡醒进入到Runnable/Blocked状态
    */
        public static void main(String[] args) {
            Object obj=new Object();
            new Thread(){
                @Override
                public void run() {
                    // 保证等待和唤醒的进程只能有一个执行
                    synchronized (obj){
                        System.out.println("正在执行的线程");
                        try {
                            obj.wait(5000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        // 唤醒后执行的代码
                        System.out.println("执行唤醒后的线程");
                    }
                }
            }.start();
    	}
    
     public static void main(String[] args) {
        Object obj=new Object();
        new Thread(){
            @Override
            public void run() {
                // 保证等待和唤醒的进程只能有一个执行
                synchronized (obj){
                    System.out.println("正在执行的线程1");
                    try {
                        obj.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    // 唤醒后执行的代码
                    System.out.println("执行唤醒后的线程1");
                }
            }
        }.start();
        new Thread(){
            @Override
            public void run() {
                // 保证等待和唤醒的进程只能有一个执行
                synchronized (obj){
                    System.out.println("正在执行的线程2");
                    try {
                        obj.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    // 唤醒后执行的代码
                    System.out.println("执行唤醒后的进程2");
                }
            }
        }.start();
        new Thread(){
            @Override
            public void run() {
    
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (obj){
                    System.out.println("唤醒等待执行的线程");
                    obj.notifyAll(); // 唤醒所有等待的线程
                }
            }
        }.start();
    }
    
  3. 线程之间的通信:多个线程在处理同一个资源,但是处理的动作(线程的任务)不同
           多个线程并发执行时, 在默认情况下CPU是随机切换线程的,当我们需要多个线程来共同完成一件任务, 并且我们希望他们有规律的执行, 那么多线程之间需要一些协调通信,以此来帮我们达到多线程共同操作一份数据。

  4. 等待与唤醒机制:就是在一个线程进行了规定操作后,就进入等待状态(wait), 等待其他线程执行完他们的指定代码过后 再将其唤醒(notify)。即多个线程在操作同一份数据时, 避免对同一共享变量的争夺。

    /*
    调用notify方法:
    	如果能获取锁,线程从WAITING状态变为RUNNABLE状态;
    	否则线程从wait set出来,又进入entry set,线程从WAITING状态变为BLOCK状态
    */
    /*
    调用wait和notify方法需要注意的事项:
    	I、必须有同一个锁对象调用
    	II、都是Object类的方法
    	III、都必须在同步代码块或者同步函数中使用
    */
    
    public class BaoZi {
        String pi;
        String xian;
        boolean flag=false;
    }
    
    public class BaoZiPu extends Thread{
        private BaoZi bz;
        public BaoZiPu(BaoZi bz){
            this.bz=bz;
        }
        @Override
        public void run()  {
            int count=0;
            while (true) {
                synchronized (bz) {
                    if (bz.flag == true) {
                        try {
                            bz.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
    
                    }
                    if (count % 2 == 0) {
                        bz.pi = "薄皮";
                        bz.xian = "三鲜";
                    } else {
                        bz.pi = "冰皮";
                        bz.xian = "牛肉大葱";
                    }
                    count++;
                    System.out.println("包子铺正在生产:" + bz.pi + bz.xian + "包子");
                    try {
                        Thread.sleep(3000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    bz.flag = true;
                    bz.notify();
                    System.out.println("包子已经生产好了");
    
                }
            }
        }
    }
    
    public class ChiHuo extends Thread {
        private BaoZi bz;
        public ChiHuo(BaoZi bz){
            this.bz=bz;
        }
    
        @Override
        public void run() {
            while (true){
                synchronized (bz){
                    if(bz.flag==false){
                        try {
                            bz.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.println("吃货正在吃"+bz.pi+bz.xian+"包子");
                    bz.flag=false;
                    bz.notify();
                    System.out.println("吃货已经把包子吃完了,包子铺开始生成包子");
                    System.out.println("------------");
                }
            }
        }
    }
    
    public class demo {
        public static void main(String[] args) {
            BaoZi bz= new BaoZi();
            new BaoZiPu(bz).start();
            new ChiHuo(bz).start();
        }
    }
    
线程池
  1. 概述:容纳道光线程的容器–> 集合(ArrayList,HashSet,LinkedList,HashMap)
  2. Executors类:工厂和工具方法Executor , ExecutorService , ScheduledExecutorService , ThreadFactory和Callable此包中定义的类。是线程池的工程类
  3. Executors的静态方法
    3.1 newFixedThreadPool​(int nThreads),创建一个线程池,该线程池重用固定数量的从共享无界队列中运行的线程。
    /*
     参数:
     	int nThread--创建线程池中包含的线程数量
     返回值:
     	ExecutorService接口,返回的是ExecutorService接口的实现类对象,可以使用ExecutorService接口来接收(面向接口编程)
     ExecutorService:线程池接口,用来从线程池中获取线程,调用start方法,执行线程任务。
     	submit​(Runnable task) 提交一个可运行的任务执行,并返回一个表示该任务的未来。 
     线程池的使用方法:
     	1、使用线程池的工厂类Executors里面的newFixedThreadPool生成一个指定线程数量的线程池
     	2、创建一个类,实现Runable接口,重写run方法,设置线程任务
     	3、调用ExecutorService中的方法submit,传递线程任务(实现类),开启线程执行run方法
     	4、调用ExecutorService中的shutdown方法,销毁线程池。
     		shutdown​(),启动有序关闭,其中先前提交的任务将被执行,但不会接受任何新任务。 
    */
        // 1.
        ExecutorService es= Executors.newFixedThreadPool(2);
        // 3.
        es.submit(new RunableImpl()); // pool-1-thread-1创建了新线程
        es.submit(new RunableImpl()); // pool-1-thread-2创建了新线程
        es.submit(new RunableImpl()); // // pool-1-thread-2创建了新线程
        // 4.
    	es.shutdown
    
    // 2.
    public class RunableImpl implements Runnable{
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName()+"创建了新线程");
        }
    }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值