java线程间通信
-
消费者类没有消费资源,生成者类生成资源
-
资源类
public class Shared {
private int resources;
private int lock;
....get set
}
- 生产者类
public class Consumer implements Runnable {
Shared shared;
public Consumer(Shared shared) {
this.shared = shared;
}
@Override
public void run() {
while (true) {
synchronized (shared) {
/*如果没有资源,则线程进入休眠状态*/
if (shared.getLock() == 0) {
try {
shared.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/*有资源,消费资源*/
shared.setResources(0);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
shared.setLock(0);
System.out.println("我是消费者,我消费了一个资源,等待生产者制造 resources="+shared.getResources());
shared.notify();
}
}
}
}
}
- 消费者类
public class Producer implements Runnable{
Shared shared;
public Producer(Shared shared) {
this.shared = shared;
}
@Override
public void run() {
while(true){
synchronized (shared){
/*如果有资源,线程则进入休眠状态*/
if (shared.getLock()==1){
try {
shared.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/*没有资源,生成资源*/
shared.setResources(10);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
shared.setLock(1);
System.out.println("我是生产者,我生产了一个资源,等待消费者来取 resources="+shared.getResources());
shared.notify();
}
}
}
}
}
- 执行代码
Shared shared=new Shared();
shared.setLock(0);
shared.setResources(0);
Producer producer=new Producer(shared);
Consumer consumer=new Consumer(shared);
new Thread(producer).start();
new Thread(consumer).start();
线程补充
- 线程池
package com.itheima.demo01.ThreadPool;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/*
线程池
在JDK1.5的时候java提供了线程池
java.util.concurrent.Executors类:线程池的工厂类,用来生产线程池
静态方法:
static ExecutorService newFixedThreadPool(int nThreads)
创建一个可重用固定线程数的线程池,以共享的无界队列方式来运行这些线程。
参数:
int nThreads:创建线程池中线程的个数
返回值:
ExecutorService:是生产线程池,类型是一个接口,newFixedThreadPool返回的就是ExecutorService接口的实现类对象
注意:我们无需关注ExecutorService的实现类是谁,我们只需要会使用ExecutorService接口来接收这个实现类即可(多态)
这叫面向接口编程
java.util.concurrent.ExecutorService:线程池
Future<?> submit(Runnable task) 提交一个 Runnable 任务用于执行,并返回一个表示该任务的 Future。
把线程任务传递给submit方法,submit方法会在线程池中获取一个线程用于执行任务;执行完毕会自动把线程在归还给线程池
Future<T> submit(Callable<T> task) 提交一个返回值的任务用于执行,返回一个表示任务的未决结果的 Future。
void shutdown() 用于销毁线程池,一般不建议使用
*/
public class Demo01ThreadPool {
public static void main(String[] args) {
//1.使用线程池工厂类Executors提供的静态方法newFixedThreadPool生产一个指定线程数量的线程池
ExecutorService ex = Executors.newFixedThreadPool(2);
//2.调用线程池ExecutorService中的方法submit,传递线程任务,执行线程任务
//new Thread(new Runnable(){}).start();
ex.submit(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"线程任务1执行了!");//pool-1-thread-2线程任务执行了!
}
});
ex.submit(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"线程任务2执行了!");//pool-1-thread-1线程任务执行了!
}
});
ex.submit(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"线程任务3执行了!");//pool-1-thread-2线程任务执行了!
}
});
//void shutdown() 用于销毁线程池,一般不建议使用
ex.shutdown();
//线程池销毁之后,就在内存中消失了,就不能在执行线程任务了
ex.submit(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"线程任务3执行了!");//RejectedExecutionException
}
});
}
}
- 用接口Callable<>类实现线程,Callable类中call方法为线程方法并且带有返回值
package com.itheima.demo01.ThreadPool;
import java.util.Random;
import java.util.concurrent.*;
/*
Future<T> submit(Callable<T> task) 提交一个返回值的任务用于执行,返回一个表示任务的未决结果的 Future。
java.util.concurrent.Callable<T>接口:用于设置线程任务
V call() 计算结果,如果无法计算结果,则抛出一个异常。
重写call方法,返回一个执行泛型类型的数据
*/
public class Demo02ThreadPool {
public static void main(String[] args) throws ExecutionException, InterruptedException {
//1.使用线程池工厂类Executors提供的静态方法newFixedThreadPool生产一个指定线程数量的线程池
ExecutorService ex = Executors.newFixedThreadPool(2);
//2.调用线程池ExecutorService中的方法submit,传递线程任务,执行线程任务,接收线程任务的返回值
Future<Double> f1 = ex.submit(new Callable<Double>() {
@Override
public Double call() throws Exception {
return 1.1;
}
});
System.out.println(f1);//java.util.concurrent.FutureTask@7006c658
//使用Future接口中的方法V get()获取线程任务的返回值
Double d = f1.get();
System.out.println(d);
Future<Integer> f2 = ex.submit(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
//返回一个0-100之间的随机数 [0,100)
return new Random().nextInt(100);
}
});
System.out.println(f2.get());
}
}