Java 线程状态、线程池

java 线程状态、线程池

1. java 的线程状态

状态 发生条件
NEW 线程刚刚被创建,没有启动,没有调用start方法
RUNNABLE(可运行) 线程已经在JVM中运行,但是是否运行不确定,看当前线程是否由CPU执行权
BLOCKED(锁阻塞) 同步代码需要获取对应的锁对象,如果锁对象被其他线程持有,则当前线程就会进入一个block状态,当当前线程持有锁对象时,进入RUNNABLE状态
WAITING(无线等待) 通过一个wait方法线程进入一个无线等待状态,需要另一个线程进行唤醒操作
TIME_WAITING(计时等待) 当前进程会在一定时间后从等待状态自动回到Runnable 状态
TERMINATED(被终止) 运行结束正常退出线程,或者在运行过程中因为异常而退出
1.1计时等待
Thread.sleep(int ms);
在对应代码块中,当前线程休眠指定时间

wait(int ms);
让当前线程进入一个计时等待状态
1.2 无限等待

当某一个线程被执行wait()方法,需要等待另外的一个线程进行唤醒操作。
public void wait();
在哪一个线程中执行,就会让当前线程进入一个无限等待状态。

1.3 唤醒操作
public void notify();
唤醒和当前锁对象有关的无限等待线程中的一个,随机选择。

public void notifyAll();
唤醒所有和当前锁对象有关的无限等待线程
1.4 使用案例
生产者—消费者问题

生产者和消费者可以说是两个不相同的线程,为了满足他们之间的同步问题,,我们可以设置一个商品类,这个商品类作为生产者和消费者的成员变量

代码演示

首先时商品类 Goods

private String name;
private float price;
private boolean product;
//getter setter方法省略
//无参的构造方法和有参的构造方法省略

针对于生产者和消费者来说,他们有相同的私有成员方法,相同的无参和有参的构造方法,此处我们让这两个类遵从Runnable接口并重写其中的run()方法。(此处代码类似,以消费者为例)
在这里插入图片描述
由于涉及到了同步问题,我们对其加锁,可以使用Lock锁,也可以使用synchronized

//消费者
public void run(){
	while (true) {
		synchronized (goods) {
			try {
			     Thread.sleep(300);
			} catch (InterruptedException e) {
			     e.printStackTrace();
			}
			// 代码a 
			if (! goods.isProduct()) {
				System.out.println("消费者购买了" + goods.getName() + ":" + goods.getPrice());
				// 修改商品标记,可以生产商品
				goods.setProduct(true);
				// 唤醒生产者
				System.out.println("唤醒生产者");
				goods.notify();
			} else {
				System.out.println("消费者进入无限等待状态");
				try{
					goods.wait();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

生产者代码仅仅在代码a以下的部分有所不同

在这里插入图片描述

2 线程池

程序可以从线程池中获取线程完成目标代码,也可以将线程归还给线程池。这样做省去了创建线程和销毁线程这样非常繁琐的操作

2.1 线程池的方法和使用
方法 作用
public static ExecutorService newFixedThreadPool(int nThreads); 得到一个线程池对象,初始化参数是要求的当前线程池的线程数
Future<?> submit(Runnable target); 从线程池中获取一个线程对象,并且执行给定的Runnable接口实现类对象作为执行目标
2.2 代码
ExecutorService service = Executors.newFixedThreadPool(5);
service.submit(() -> System.out.println(Thread.currentThread().getName() + " 明天吃土"));
  service.submit(() -> System.out.println(Thread.currentThread().getName() + " 明天吃土豆"));
  service.submit(() -> System.out.println(Thread.currentThread().getName() + " 明天吃土豆牛"));
  service.submit(() -> System.out.println(Thread.currentThread().getName() + " 明天吃土豆牛腩"));
  service.submit(() -> System.out.println(Thread.currentThread().getName() + " 明天吃土豆牛腩啊"));

输出结果
在这里插入图片描述
如果需要的线程数比线程池中的线程还多的话,多余的线程会等待其他线程完成后,继续执行,而不是在线程池中创建新的线程。

发布了13 篇原创文章 · 获赞 17 · 访问量 3951

猜你喜欢

转载自blog.csdn.net/weixin_43932553/article/details/104639135