java Java线程简单队列
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9916264/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java thread simple queue
提问by ioni
I'm trying to create a simple queue with Java Thread that would allow a loop, say a for loop with 10 iterations, to iterate n (< 10) threads at a time and wait until those threads are finished before continuing to iterate.
我正在尝试使用 Java 线程创建一个简单的队列,该队列将允许循环,例如具有 10 次迭代的 for 循环,一次迭代 n (< 10) 个线程并等到这些线程完成后再继续迭代。
Here's a better way to illustrate my problem:
这是说明我的问题的更好方法:
for (int i = 1; i <= 10; i++) {
new Thread ( do_some_work() );
if ( no_available_threads ) {
wait_until_available_threads();
}
}
do_some_work() {
// do something that takes a long time
}
Basically what I want to do is a copy of this: Thread and Queue
基本上我想做的是一个副本:线程和队列
How can I achieve this the most painless way?
我怎样才能以最无痛的方式实现这一目标?
回答by Gray
I would use the Java 5 Executors
instead of rolling your own. Something like the following:
我会使用 Java 5Executors
而不是滚动你自己的。类似于以下内容:
ExecutorService service = Executors.newFixedThreadPool(10);
// now submit our jobs
service.submit(new Runnable() {
public void run() {
do_some_work();
}
});
// you can submit any number of jobs and the 10 threads will work on them
// in order
...
// when no more to submit, call shutdown
service.shutdown();
// now wait for the jobs to finish
service.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
回答by RalphChapin
Use the Executors, as recommended by the others. However, if you want the fun of doing it yourself, try something like this. (Take care. I wrote it in Notepad and there's some Exceptions you'll need to catch even if I got everything else right. Notepad's poor at catching coding errors.) This is more a concept than an actual solution to anything, but the idea could be generally useful.
按照其他人的建议使用 Executors。但是,如果您想要自己动手做的乐趣,请尝试这样的操作。(小心。我是用记事本写的,即使我把其他一切都做对了,你也需要捕捉一些异常。记事本在捕捉编码错误方面很差。)这更像是一个概念,而不是任何实际解决方案,但这个想法可能普遍有用。
private ConcurrentLinkedQueue<MyThread> tQueue =
new ConcurrentLinkedQueue<MyThread>();
class MyThread extends Thread {
public Runnable doSomething;
public void run() {
// Do the real work.
doSomething();
// Clean up and make MyThread available again.
tQueue.add( mythread );
// Might be able to avoid this synch with clever code.
// (Don't synch if you know no one's waiting.)
// (But do that later. Much later.)
synchronized (tQueue) {
// Tell them the queue is no longer empty.
tQueue.notifyAll();
}
}
}
Elsewhere:
别处:
// Put ten MyThreads in tQueue.
for (int i = 0; i < 10; i++) tQueue.add( new MyThread() );
// Main Loop. Runs ten threads endlessly.
for (;;) {
MyThread t = tQueue.poll();
if (t == null) {
// Queue empty. Sleep till someone tells us it's not.
do {
// There's a try-catch combo missing here.
synchonized( tQueue ) { tQueue.wait() };
t = tQueue.poll();
} while (t == null) break; // Watch for fake alert!
}
t.doSomething = do_some_work;
t.start();
}
Also, note the clever use of ConcurrentLinkedQueue. You could use something else like ArrayList or LinkedList, but you'd need to synchronize them.
另外,请注意 ConcurrentLinkedQueue 的巧妙使用。您可以使用其他类似 ArrayList 或 LinkedList 的东西,但您需要同步它们。
回答by RalphChapin
Crate Logger.class
:
板条箱Logger.class
:
public class Logger extends Thread {
List<String> queue = new ArrayList<String>();
private final int MAX_QUEUE_SIZE = 20;
private final int MAX_THREAD_COUNT = 10;
@Override
public void start() {
super.start();
Runnable task = new Runnable() {
@Override
public void run() {
while (true) {
String message = pullMessage();
Log.d(Thread.currentThread().getName(), message);
// Do another processing
}
}
};
// Create a Group of Threads for processing
for (int i = 0; i < MAX_THREAD_COUNT; i++) {
new Thread(task).start();
}
}
// Pulls a message from the queue
// Only returns when a new message is retrieves
// from the queue.
private synchronized String pullMessage() {
while (queue.isEmpty()) {
try {
wait();
} catch (InterruptedException e) {
}
}
return queue.remove(0);
}
// Push a new message to the tail of the queue if
// the queue has available positions
public synchronized void pushMessage(String logMsg) {
if (queue.size() < MAX_QUEUE_SIZE) {
queue.add(logMsg);
notifyAll();
}
}
}
Then insert bellow code in your main class :
然后在你的主类中插入波纹管代码:
Logger logger =new Logger();
logger.start();
for ( int i=0; i< 10 ; i++) {
logger.pushMessage(" DATE : "+"Log Message #"+i);
}
回答by ControlAltDel
see java.util.concurrent and especially Executors and ExecutorService
参见 java.util.concurrent 尤其是 Executors 和 ExecutorService