在Java中使用多个线程
我是并发编程的新手,一直在编写代码,其中有一个要处理的项目队列,该队列被传递给一些工作线程,数量由用户指定。目前,我只是尝试使用两个辅助线程加上主线程在Java中使用多个线程,java,multithreading,concurrency,task-queue,worker,Java,Multithreading,Concurrency,Task Queue,Worker,我是并发编程的新手,一直在编写代码,其中有一个要处理的项目队列,该队列被传递给一些工作线程,数量由用户指定。目前,我只是尝试使用两个辅助线程加上主线程 private static class workerThread extends Thread { workerThread(){ super(); } public void run(){ while (!workQueue.isEmpty
private static class workerThread extends Thread {
workerThread(){
super();
}
public void run(){
while (!workQueue.isEmpty()) {
String x = workQueue.remove();
//System.out.println("work queue size: " + workQueue.size());
Vector<String> list2 = new Vector<String>((Vector) table.get(x));
list2 = process(x, list2);
//System.out.println(list2 + "list2");
table.put(x, list2);
//System.out.println(x + "key" + "value" + vvv);
}
}
我不确定这是否正确,或者是否会因为等待加入而有任何好处?感谢您的帮助。一种更简洁、更具可扩展性的方法是使用类创建的线程池
顺便说一句,
Vector
类已经过时,不应该再使用了-改用ArrayList
,把你学会使用Vector的任何书籍或教程都扔掉-它已经过时十多年了。只是一些参考资料,我想您应该使用阻塞队列
以及执行服务
和可运行
或可调用
final ExecutorService executor=Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors())代码>甚至可能是一个实例变量(私有静态最终执行器服务池=…)。对于I/O绑定的应用程序,您可能希望使用比可用处理器更多的线程。然后,您又不想使用向量
。使用另一个列表
实现(通常要使用的是ArrayList
)
顺便说一句:如果你想掌握并发编程,你可能还想了解Akka和Actors/STM,而不是使用通常的共享可变性模型
编辑:我肯定会推荐Josh(ua)Bloch提供的高效Java。您一定要使用Executors。这是一个仅供参考的例子。它只在一个线程上工作,但我认为这对您来说是一个好的开始。它很容易适应任意数量的线程
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<MyObject> f =
executor.submit(new Callable<MyObject>() {
@Override
public MyObject call() throws Exception {
MyObject obj = new MyObject();
// do stuff
return obj;
}
});
MyObject myObject =
new MyObject();
try {
myObject = f.get(500, TimeUnit.MILLISECONDS);
}
catch (InterruptedException e) {
// stuff
}
catch (ExecutionException e) {
// stuff
}
catch (TimeoutException e) {
// stuff
}
finally {
executor.shutdown();
}
ExecutorService executor=Executors.newSingleThreadExecutor();
未来f=
执行人提交(新的可调用(){
@凌驾
公共MyObject调用()引发异常{
MyObject obj=新的MyObject();
//做事
返回obj;
}
});
肌体肌体=
新的MyObject();
试一试{
myObject=f.get(500,时间单位为毫秒);
}
捕捉(中断异常e){
//东西
}
捕获(执行例外){
//东西
}
捕获(超时异常e){
//东西
}
最后{
executor.shutdown();
}
在本例中,我希望在超时之前最多等待500毫秒,但这是可选的。
希望这能有所帮助。我想Sarconi会从理解线程中获益。我看了一下线程池,但这个练习似乎有点复杂。哦,我用了一个向量,因为它是同步的。我没有意识到它已经过时了。从C++开发中,我可以肯定的说,仅仅为了精神一致,很难不使用<代码>向量<代码>。并不是说它更好,只是这可能是海报使用它的原因。@Sarconi:它肯定不会比手动管理可变数量的线程更复杂。当每个实例一次只被一个线程使用时,向量的同步似乎不相关。java Future.get==blocking==killsscalability@ViktorKlang:你有更多的信息吗?我想更深入地讨论这个话题。你能分享一些链接吗?10xblocking==暂停线程==活动线程数减少==可以完成的工作量减少==可伸缩性减少==性能降低在您的示例中,您有两个线程,调用方和ExecutorService中的线程。当您执行Future.get时,这意味着您有1个线程暂停,1个线程正在工作。如果有100个呼叫者,则有100个线程暂停,1个线程正在工作。
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<MyObject> f =
executor.submit(new Callable<MyObject>() {
@Override
public MyObject call() throws Exception {
MyObject obj = new MyObject();
// do stuff
return obj;
}
});
MyObject myObject =
new MyObject();
try {
myObject = f.get(500, TimeUnit.MILLISECONDS);
}
catch (InterruptedException e) {
// stuff
}
catch (ExecutionException e) {
// stuff
}
catch (TimeoutException e) {
// stuff
}
finally {
executor.shutdown();
}