方式一: LockSupport.unpark(Thread1) 与 LockSupport.park()
方式二:定义一个volatile的变r,自旋锁
方式三:两个阻塞队列capacity=1,先从队列里面取值,取到值就输出,取不到就阻塞等待
方式四:synchronize、wait、notify
注意遍历输出完之后要notify对方,否则对方会一直wait
方式五:lock.new两个condition,T1在condition1上等待,输出后通知condition2,T2在condition2上等待,输出后通知condition1
@Bean
public ThreadPoolTaskExecutor threadPoolTaskExecutor(){
ThreadPoolTaskExecutor poolTaskExecutor = new ThreadPoolTaskExecutor();
// 核心线程数
poolTaskExecutor.setCorePoolSize(10);
// 线程池维护线程的最大数量,只有在缓冲队列满了之后才会申请超过核心线程数的线程
poolTaskExecutor.setMaxPoolSize(100);
// 缓存队列
poolTaskExecutor.setQueueCapacity(50);
// 核心线程之外的线程在空闲时间到达之后会被销毁
poolTaskExecutor.setKeepAliveSeconds(200);
// 异步方法内部线程名称
poolTaskExecutor.setThreadNamePrefix("myThread-");
// n当然不是只有CallerRunsPolicy一种可选
poolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
poolTaskExecutor.initialize();
return poolTaskExecutor;
}
ThreadPoolExocutor 是一个executor
ThreadPoolTaskExecutor 是一个executor,还有定时调度功能
ExecutorService也是一个executor,
ScheduledExecutorService还是一个executor
newFixedThreadPool(),newCachedThreadPool() 等几个方法,
实际上也是间接调用了ThreadPoolExocutor ,不过是传的不同的构造参数
Runnable task1 = new Runnable() {
@Override
public void run() {
while (true) {
System.out.println("111");
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
ExecutorService executorService = Executors.newFixedThreadPool(1);
ExecutorService executorService1 = Executors.newSingleThreadExecutor();
executorService.execute(task1);
class TaskWithResult implements Callable<Integer> {
@Override
public Integer call() throws Exception {
return 1024;
}
}
ExecutorService executorService = Executors.newFixedThreadPool(1);
Future<Integer> submit = executorService.submit(new TaskWithResult());
// 阻塞直到等待结果返回
// V get(long timeout, TimeUnit unit)也可以指定等待时间
Integer integer = submit.get();
// 判断是否已经返回结果
boolean done = submit.isDone();
不一定,非后台线程结束,后台线程也会结束,不会执行finally了
try {
ExecutorService executorService = Executors.newFixedThreadPool(1);
executorService.execute(exceptionTask);
}catch (Exception e) {
// 捕获无效,依然会在控制台打印异常
e.printStackTrace();
}
只会执行一个线程,而且会一直等这个线程执行完毕
static class Task1 implements Runnable{
private Object object;
public Task1(Object object) {
this.object = object;
}
@Override
public void run() {
synchronized (object) {
System.out.println("task1..begin");
try {
object.notifyAll();
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("task1..end");
object.notifyAll();
}
}
}
static class Task2 implements Runnable{
private Object object;
public Task2(Object object) {
this.object = object;
}
@Override
public void run() {
synchronized (object) {
System.out.println("task2..begin");
try {
object.notifyAll();
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("task2..end");
object.notifyAll();
}
}
}
ExecutorService executorService = Executors.newFixedThreadPool(1);
executorService.execute(new Task1(lock));
executorService.execute(new Task2(lock));
ReentrantLock lock = new ReentrantLock();
lock.lock();
finally {
lock.unlock();
}
lock.tryLock();
// 若锁被其他线程获取,等待两秒
lock.tryLock(2,TimeUnit.SECONDS);
Condition condition = lock.newCondition();
condition.signalAll();
condition.await();
// 让出锁两秒,然后继续竞争锁
condition.await(2,TimeUnit.SECONDS);
// java编程思想 704
1.一个任务是将蜡涂在汽车上,另外一个是抛光汽车,先涂蜡,再抛光,再涂蜡再抛光,重复10次
// java编程思想 709
2.饭店里面有1厨师和1服务员,服务员等待厨师准备好膳食,当厨师准备好,通知服务员取走膳食
// java并发编程,715
1.一台机器具有三个任务,一台制作吐司,一台给吐司抹黄油,一台在抹过黄油的吐司涂果酱
1.一个分析获得数据的任务,两个渲染数据到模板的任务,主线程返回静态页的任务。使用闭锁,控制最后返回静态页
2.先要分析得到数据,然后再开两个任务将数据渲染到两个模板,仅当一个模板渲染完成之后最后返回静态页
允许N个任务同时访问这项资源
用于两个任务交换对象,对象在创建的同时被消费
定时任务还有quartz框架
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(10);
// 延迟一秒启动,每隔两秒启动一次
scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
System.out.println("ScheduledTask");
}
}, 1, 2, TimeUnit.SECONDS);
// 延迟一秒启动,执行一次
scheduledExecutorService.schedule(new Runnable() {
@Override
public void run() {
System.out.println("ScheduledTask");
}
},1, TimeUnit.SECONDS);