java并发基础多线程学习(6)-线程池的使用
场景如下:100张票。多个线程同时执行任务去卖。买完就退出。用到的技术:
线程池技术:
1:Executors线程池工具类可以通过该工具类创建固定线程数量的线程池也可以构建缓存线程池。这里构建固定数量
的线程池。
2:CallAble接口。类似Runnable接口。可以通过该接口创建任务丢给Executors创建的线程去执行任务。该接口有两个地方
是Runnable接口不具备的。(1):该接口有返回值。当你需要在执行某个任务是否。如果需要另外异步执行一个计算任务。并且该
计算任务比较耗时而且需要返回值的时候。可以使用该接口。(2)该接口提供一个cancle方法。手动停止任务的执行。当xxx就
cancel任务。这个可以根据实际情况而定。最后注意执行完毕要把线程池shutdown()。
3:多线程并发访问共享变量。要保证执行任务方法加上锁。具体代码如下:
package com.nuanshui.frms.native1.thread;
import java.util.concurrent.*;
/**
* @author liyy
* @description:线程池
* @date 2019-03-27 21:18
* @program frms-parent
*/
public class ThreadPool {
//通过Executors创建指定数量线程的线程池,然后同时执行n个任务执行
public static void main(String[] args){
ExecutorService threadPool = Executors.newFixedThreadPool(10);//固定线程数量的线程池
// ExecutorService threadPool = Executors.newCachedThreadPool();//缓存线程池。可以根据执行任务数量创建线程数量
ShareTicket shareTicket = new ShareTicket();
/*for(int i=0;i<10;i++){
final int task = i;
threadPool.execute(new Runnable() {
@Override
public void run() {
for(int j=1;j<=10;j++){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
shareTicket.sell();
// System.out.println(Thread.currentThread().getName()+"执行任务"+task);
}
}
});
}*/
int task = 0;
while (true){
task++;
Future<String> result = threadPool.submit(new Callable<String>() {
@Override
public String call() throws Exception {
int count = shareTicket.sell();
return String.valueOf(count);
}
});
try {
if(result!=null && "0".equals(result.get())){
System.out.println("所有任务执行完毕"+task);
threadPool.shutdown();
break;
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
}
class ShareTicket{
public int ticketTotal = 100;
public int sell() {
synchronized (this){
if(ticketTotal>0){
System.out.println(Thread.currentThread().getName()+"消费一张票");
ticketTotal -- ;
System.out.println("剩余票数:"+ticketTotal);
}else{
System.out.println("票买完了");
}
return ticketTotal;
}
}
}
代码经过测试:结果如下: