我有多个线程打印数据。所有数据都打印出来;然而,他们不是为了。含义线程2开始打印,而线程1尚未完成,这会导致不一致。我如何保证一致性?含义一旦线程1完成,线程2可以打印。Java - Println不是为了
回答
从你的意见,你正在寻找实现1 1 1 1 2 2 2 2
所以你需要做的实际上是等待线程1完成,然后再启动线程2,是这样的:
Thread1 thread1 = new Thread1();
Thread2 thread2 = new Thread2();
thread1.start();
thread1.join(); // This waits for Thread1 to finish before starting Thread2
thread2.start();
但是,如果你想有两个线程开始,但有线程2等待通过其处理部分的方式,在等待线程1完成 - 这可以通过一些技巧来完成 - 一个特别想到的 - 使用Semaphore.
例子:
好吧,首先确定你的线程构造函数接受一个信号量,从而:
// Thread2 would be identical wrt the semaphore
public Thread1(Semaphore semaphore) throws InterruptedException
{
this.semaphore = semaphore; // store semaphore locally
semaphore.acquire(2);
}
线程1的run方法应该是这样的:
public void run()
{
// .... processing...
// ... print stuff
System.out.println("1 1 1 1");
semaphore.release(); // release 1 permit, allowing thread2 to continue
// ... more processing
semaphore.release(); // release last permit.
}
线程2的run方法看起来应该类似于此:
public void run()
{
int permits = 2;
try
{
// .... processing...
semaphore.acquire(1); // acquire one more permit (will block until Thread1 releases one)
permits++;
// ... print stuff
System.out.println("2 2 2 2");
// ... more processing
}
catch (InterruptedException ie)
{
// interrupted
}
semaphore.release(permits); // release permits.
}
现在,设置线程可以这样完成:
try
{
Semaphore semaphore = new Semaphore(4); // 4 permit semaphore
Thread1 thread1 = new Thread1(semaphore);
Thread2 thread2 = new Thread2(semaphore);
thread1.start();
thread2.start();
semaphore.acquire(4);
}
catch (InterruptedException ie)
{
// interrupt logic...
}
你能举个例子吗?谢谢。 –
如果你只是一次只运行一个线程,为什么还要有线程呢? –
信号量方法将允许两个线程同时执行处理,但允许一个线程中途暂停,允许其他线程继续处理,然后再恢复自己...现在正在编写示例... – Crollster
这是线程是如何工作的。如果你启动两个线程它就会像这样1 2 1 2 1 2 1 2
是的,这是事实。我想实现1 1 1 1 2 2 2 2 –
不,它不会。订单没有保证。 –
一旦run方法在一个线程已经完成调用它的东西在线程2让它知道它可以打印
我们无法计算线程何时运行并完成执行。它完全取决于CPU。你可以做的是在第一个线程结束时将一个标志变量更新为一个值,并在第二个线程执行之前检查该值。
你必须保存线程2输出并打印它,直到线程1为止。按照建议的顺序执行它们也会起作用,但那么为什么要使用Thread?
如果您希望线程1执行的代码在运行线程2之前完成,那么您不需要线程。您可能想看看Java的ExecutorService
。具体而言,Executors. newSingleThreadExecutor()
。这将允许您安排任务在另一个线程中运行,但要确保它们按顺序运行。
所以,这里是你想要做的(伪代码)是什么:
String results[2];
Thread1 thread1 = new Thread1() {
public void run() {
// do stuff; collect output
results[0] = output
}
};
Thread2 thread1 = new Thread1() {
public void run() {
// do stuff; collect output
results[1] = output
}
};
thread1.start();
thread2.start();
thread1.join();
thread2.join();
print result[0];
print result[1];
上面有利用java.util.concurrent类做的更好的方法,但是这应该给你一个想法
只有数据输出被串行化,而不是主要处理。所以你可能仍然会赢得胜利(当然,这取决于运行方法内部发生了什么)。 –
对不起 - 评论不好的帖子! –
您不能随机从多个线程打印,并预计任何命令。
如果你需要按照有序的方式输出,那么你将不得不同步这些线程(从而破坏具有多个线程的目的),或者让线程回传信息以便输出回主线程它可以处理订购和输出它。
编辑:因为我很无聊。
如果你想通过线程并行化一些工作然后输出结果,你需要让线程将他们工作的产品传回给主线程并让它做输出。一种方法,这是使用队列(这是简单的例子,它依赖线程顺序 - 你可能需要把所有的结果和关联/排序/等):
public class Worker implements Runnable
{
private ConcurrentLinkedQueue<Integer> outputQueue;
public Worker(ConcurrentLinkedQueue<Integer> outputQueue)
{
this.outputQueue = outputQueue;
}
@Override
public void run()
{
// Do whatever it is you're doing
...
// place result on queue
outputQueue.add(result);
}
}
public class Main
{
static void main(String[] args)
{
ArrayList<ConcurrentLinkedQueue<Integer>> myQueues =
new ArrayList<ConcurrentLinkedQueue<Integer>>();
Thread[] myThreads = new Thread[numThreads];
// Create queue, create thread with Worker(queue),
// start thread
for (int i = 0; i < numThreads; i++)
{
ConcurrentLinkedQueue<Integer> queue =
new ConcurrentLinkedQueue<Integer>();
myQueues.add(queue);
myThreads[i] = new Thread(new Worker(queue)).start();
}
// Wait for all threads to finish, print their results
for (int i = 0; i < numThreads; i++)
{
join(myThreads[i]);
// Get the queue for the thread we just joined,
// pull off each result and output
Integer j;
while ((j = myQueues.get(i).poll()) != null)
{
System.out.println(j);
}
}
}
}
这关的。上面有我头,但这是一般的方法
- 1. Java是为了
- 2. Slashy字符串文字不是的println
- 3. 为什么我的println不工作?
- 4. 想让输出作为对象,而不是的println
- 5. 标准方法名称,为什么println中的l不是大写?
- 6. java println语句中+符号的含义
- 7. Java的println插入额外的新行
- 8. Java:将一个数组传递给println
- 9. 这个Java println调用中的char转换是做什么的?
- 10. 什么是系统的,在的println的System.out.println()在Java中
- 11. 是否有可能回想一下Java中的println?
- 12. 是否为Java实现了PKCS#1 V2.0?
- 13. java |运营商是为了什么?
- 14. Java - Android - ZIP文件不断带回println需要消息错误
- 15. 的URLConnection看来是不行了的Java
- 16. 调用的println
- 17. println(f(a))是什么意思?
- 18. Println打印方括号但界面不是一个切片
- 19. 在android编程中不允许登录到println吗?为什么?
- 20. 为什么这个println命令不会启动一个新行?
- 21. Jquery是否为Java/Java EE程序员增加了价值?
- 22. Println无法找到符号
- 23. 詹金斯2.0 pipline的println不工作
- 24. 的println和反射
- 25. println vs scala的System.out.println
- 26. 系统输出println
- 27. 了解样本期中考试,多班与println
- 28. 打印Writer写()和println()
- 29. java的构造为了
- 30. 为了评估在Java中
你想要两个线程同时执行或线程1完成其运行后执行线程2吗? –
线程1完成其运行后执行线程2 –
那么为什么你需要两个线程呢?线程背后的全部想法是同时运行代码。 –