1. 准备一个任务容器
2. 一次性启动多个线程
3. 刚开始任务容器是空的,所以线程都 wait 在上面。
4. 直到一个外部线程往这个任务容器中扔了一个“任务”,就会有一个线程被 唤醒notify
5. 这个线程取出“任务”,并且 执行这个任务 ,执行完毕后,继续等待下一次任务的到来。
2. 一次性启动多个线程
3. 刚开始任务容器是空的,所以线程都 wait 在上面。
4. 直到一个外部线程往这个任务容器中扔了一个“任务”,就会有一个线程被 唤醒notify
5. 这个线程取出“任务”,并且 执行这个任务 ,执行完毕后,继续等待下一次任务的到来。
6. 如果短时间内,有较多的任务加入,那么就会有多个线程被唤醒,去执行这些任务。
上面是线程池思路上的我们根据这几点大概设计一个线程池来
public class ThreadPool {
//1. 准备一个任务容器
LinkedList<Runnable> tasks = new LinkedList<>();//存储要执行的任务
int size;
//2. 一次性启动多个线程
public ThreadPool(int size)
{
this.size=size;
for(int i=0;i<size;i++)
{
new WorkThread("工作线程"+i).start();
}
}
//4. 直到一个外部线程往这个任务容器中扔了一个“任务”,就会有一个线程被唤醒notify
public void add(Runnable task)
{
synchronized(tasks)
{
if(tasks.size()<10)
{
tasks.add(task);
}
tasks.notifyAll();//唤醒工作线程执行任务
}
}
//执行任务的内部类
class WorkThread extends Thread{
String name;
Runnable task;
public WorkThread(String name) {
super();
this.name = name;
}
@Override
public void run()
{
System.out.println(this.name+"启动");
while(true)
{
synchronized(tasks)
{
//3. 刚开始任务容器是空的,所以线程都wait在上面。
while(tasks.isEmpty())//如果为空线程池等待
{
try {
tasks.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
tasks.notifyAll();// 允许添加任务的线程可以继续添加任务
}
//5. 这个线程取出“任务”,并且执行这个任务,执行完毕后,继续等待下一次任务的到来。
this.task = tasks.removeLast();//拿出一个要执行的任务
}
System.out.print(this.getName() + "获取到任务 ");
System.out.print("执行");
task.run();
}
}//run
}//class WorkThread
}
测试类
开两个线程往线程池里加任务
public class test {
public static void main(String[] args) {
ThreadPool pool = new ThreadPool(10);
Thread t1= new Thread(new Runnable()
{
@Override
public void run() {
for(int i=0;i<10;i++)
{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
int index=i;
pool.add(new Runnable()
{
@Override
public void run()
{
System.out.println("线程1中的任务"+index);
}
});//线程池中添加任务
}//for
}//run
});//Thread
Thread t2= new Thread(new Runnable()
{
@Override
public void run() {
for(int i=0;i<10;i++)
{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
int index=i;
pool.add(new Runnable()
{
@Override
public void run()
{
System.out.println("线程2中的任务"+index);
}
});//线程池中添加任务
}//for
}//run
});//Thread
t1.start();
t2.start();
}
}
测试结果
这样我们就实现了一个可以不停执行任务的线程池
参考资料 线程池