线程池的原理:
它是一种预创建技术,预先创建一定数量的线程,内部有一个阻塞队列是用来存放任务的,
池对象提供一个接口来添加任务进阻塞队列,各个空闲的线程从阻塞队列中取任务执行;
线程数量是有限制,创建线程时需要消耗时间
线程的数量不能跟随任务的数量 , 只能是适量的线程数 ,线程要重复利用
public class Demo2 {
public static void main(String[] args) {
List<Runnable> tasklist = new LinkedList<>();
for (int i=0;i<1000;i++){ //创建1000条子线程
final int j = i;
tasklist.add(new Runnable() {
@Override
public void run() {
System.out.println("线程["+Thread.currentThread().getId()+"],从第 :"+j+"开始执行");
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});// 该线程还没有放入运行队列 start() 运行一遍,故1=1000
}
//线程池的重点
ExecutorService pool = new ScheduledThreadPoolExecutor(10);
// Exception pool = new MyThreadDemo(10);
new Thread(new Runnable() {
@Override
public void run() {
String s = new Scanner(System.in).nextLine();//输入一个文本内容
pool.shutdown();
//((MyThreadDemo) pool).stop();
while (true){
System.out.println("Pool.isShutDown() is "
);
}
}
}).start();//放入运行队列
for (int i=0;i<tasklist.size();i++){
pool.execute(tasklist.get(i));
// ((MyThreadDemo) pool).execute(tasklist.get(i));
}
}
}
异步与同步:
A方法调用B方法,但A和B是在不同的线程中执行,就叫异步调用 / 异步执行
如果A和B在同一个线程中执行,就叫同步调用;
异步执行是为了提高效率,可以使用 callable 接口和 SchedulepooleExcutor 类来实现异常调用和跨线程取数据;
//异步调用
public class DyDemoOK {
public static void main(String[] args) throws ExecutionException, InterruptedException { methodA(); }
public static void methodA() throws ExecutionException, InterruptedException {
System.out.println("methodA的线程:"+Thread.currentThread().getId());
// Callable<String> callable =new Callable<String>() {
// @Override
// public String call() throws Exception {
// return methodB();
// }
// };
// //ScheduledThreadPoolExecutor是一个使用线程池执行定时任务的类
// ScheduledThreadPoolExecutor pool = new ScheduledThreadPoolExecutor(2);
// ScheduledFuture<String > scheduled = pool.schedule(callable,10, TimeUnit.MILLISECONDS);
// String data = scheduled.get();
// System.out.println("methodA方法要吃:"+data);
//改进后
System.out.println("methodA吃到:"+new ScheduledThreadPoolExecutor(2).schedule(
new Callable<String>() {
@Override
public String call() throws Exception {
return methodB();
}
},3,TimeUnit.MILLISECONDS
).get());
}
public static String methodB(){
System.out.println("methodB()的线程:"+Thread.currentThread().getId());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "粽子";
}
}