在这个多线程程序中,当我运行它时,我总是以一些随机顺序获得输出。但我想知道是否有任何方法可以让这个程序在同步模式下工作。就像我嚼它然后第一个线程它应该打印出所有内容,然后第二个线程它应该打印出来的东西,然后第三个线程它应该打印出所有等等。所以每个线程的样本输出应该是这样的 - / p>
Task 1 Started
original: Hello World
Difference:- 0
Task 1 Ended
Task 2 Started
original: Hello World
Difference:- 0
Task 2 Ended
............
............
Task 15 Started
original: Hello World
Difference:- 0
Task 15 Ended
这是我的下面的程序。任何建议将不胜感激。
class ThreadTask implements Runnable {
private int id;
public ThreadTask(int id) {
this.id = id;
}
public synchronized void run() {
System.out.println("Task " + id + " Started ");
String originalString = "Hello World";
System.out.println("original: " + originalString);
System.out.println("Task " + id + " Ended ");
}
}
public class TestPool {
public static void main(String[] args) throws InterruptedException {
int size = 5; //Integer.parseInt(args[0]);
// create thread pool with given size
ExecutorService service = Executors.newFixedThreadPool(size);
// queue some tasks
for(int i = 1; i <= 3 * size; i++) {
service.submit(new ThreadTask(i));
}
// wait for termination
service.shutdown();
service.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
}
}
答案 0 :(得分:4)
您对Jakub的答案评论如下:
在我开始学习线程时,你能给我一些关于我的代码的示例基础吗?这对我有很大的帮助。
Jakub所说的是强制线程以固定顺序运行会破坏首先使用线程的目的。 想一想。
如果您确实希望/需要您的示例按顺序运行任务,您可以这样做:
for (int i = 1; i <= 3 * size; i++) {
new ThreadTask(i).run();
}
即。只需在当前线程中运行runnable。
或者您可以将最大池大小设置为1,这会强制服务按顺序运行任务。 (当然,这会破坏使用线程的重点。你不会以这种方式得到任何并行性。)
更明智的方法是让每个线程在Future中返回其结果,然后让主线程从每个未来(按所需顺序)获取值并打印它。基本上,您希望允许线程以任何顺序运行(并行,如果您有多个核心),但在访问结果时强制执行排序。
答案 1 :(得分:2)
线程的本质是它们可以同时运行,如果你希望它们按顺序运行,就不要使用Thread。
还有另一种要求,也许你想要几个工作(同时),但按照给定的顺序。在这种情况下,我强烈建议您实施排队系统。也就是说,建立一个像
这样的队列Queue <C> q
一个帖子
class T implements Runnable {
public void run() {
while (!q.empty()) {
// Do something
}
}
}
您可以通过ExecutorService使用Runnable,就像您使用过的代码一样。
您还可以在之前代码的“执行某事”部分中将一些元素添加到队列中,然后您可以自己控制作业的顺序。
答案 2 :(得分:0)
您可以保存对前一个线程的引用,并使用join()
将下一个线程连接到上一个线程。这将确保线程将以一系列运行(下一个线程不会启动,除非前一个完成)。但这样做的目的是让我望而却步。
public class TestPool
{
static class ThreadTask extends Thread
{
private int id;
private Thread previous;
public ThreadTask(int id, Thread previous){
this.id = id;
this.previous = previous;
}
public void run(){
if(previous != null){
try{
previous.join();
}
catch(InterruptedException e){
e.printStackTrace();
}
}
System.out.println("Task " + id + " Started ");
String originalString = "Hello World";
System.out.println("original: " + originalString);
System.out.println("Task " + id + " Ended ");
}
}
public static void main(String[] args) throws InterruptedException{
int size = 5; // Integer.parseInt(args[0]);
// create thread pool with given size
ExecutorService service = Executors.newFixedThreadPool(size);
Thread previous = null;
// queue some tasks
for(int i = 1; i <= 3 * size; i++){
Thread thread = new ThreadTask(i, previous);
previous = thread;
thread.start();
//service.submit(thread);
}
// wait for termination
//service.shutdown();
//service.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
}
}
未经测试,sry。我不知道ExecutorService
正在做什么,它可能会打破这个。请注意,我需要成为Thread
,Runnable
是不够的。此外,run()
无需同步,因为每次执行只会调用一次。并且您不应该使用run()
启动线程,而应使用start()
。
编辑:我只是试图运行它,并且ExecutorService正在提供帮助。如果你只是启动线程(就像我的代码那样),那么它就可以了。