您可以使用semaphore
和wait/notify
方法来完成您正在尝试做的事情。方法是:
semaphore
一次允许的最大线程数初始化。
- 等到任务可用
queue
。
- 获取一个
semaphore
.
- 运行任务并在完成时释放
semaphore
.
将所有四个步骤都放在永远的 while 循环中,您就可以使用任务执行器了。这仅用于学习目的,正如@fge 所说,已经存在ThreadPoolExecuter
可以为您做同样事情并且更加优化的东西。
import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.Semaphore;
public class ThreadExecuter extends Thread {
Queue<Runnable> tasks = new LinkedList<Runnable>();
Semaphore s;
Object bin = new Object();
public ThreadExecuter(int n) {
s = new Semaphore(n);
}
public void addTask(Runnable r) {
synchronized (bin) {
tasks.add(r);
bin.notifyAll();
}
}
public void run() {
while (true) {
try {
final Runnable r;
synchronized (bin) {
while (tasks.isEmpty())
bin.wait();
r = tasks.poll();
}
s.acquire();
new Thread() {
public void run() {
r.run();
s.release();
}
}.start();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
主要方法如下所示:
import java.util.Random;
public class ThreadTest {
/**
* @param args
*/
public static void main(String[] args) {
/* to make maximum 10 threads each running 1 runnable */
ThreadExecuter executer = new ThreadExecuter(10);
executer.start();
for(int i = 0; i < 5000; i++) {
/* add task in executer, this is non blocking */
executer.addTask(new Runnable() {
@Override
public void run() {
System.out.println("Task Executed in "
+ Thread.currentThread().getId());
try {
Thread.sleep(new Random().nextInt(8000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
}
}