我有多個線程打印數據。所有數據都打印出來;然而,他們不是爲了。含義線程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. 爲什麼println不顯示 - Java
- 2. 不同在Java的println()的行爲
- 3. Java是爲了
- 4. 的Java:語句不是爲了
- 5. Blackjack println遊戲Java編程
- 6. java arraylist hashmap如何println
- 7. Java的println()的整數?
- 8. java中的Println null參數
- 9. Java內部println問題()
- 10. JAVA的PrintWriter的println方法
- 11. Slashy字符串文字不是的println
- 12. 爲什麼我的println不工作?
- 13. 找不到符號println
- 14. 是JAVA中的println方法訪問器還是mutator?
- 15. 想讓輸出作爲對象,而不是的println
- 16. 調用someRDD.collect.foreach(println)與someRDD.foreach(println)
- 17. 與println錯誤:位置類,方法println()
- 18. Java的Web應用程序println語句顯示了Tomcat的控制檯上而不是在日誌文件中
- 19. SQL INSERT不是爲了
- 20. 標準方法名稱,爲什麼println中的l不是大寫?
- 21. 如何在android中使用println java?
- 22. 的Java while循環沒有的println
- 23. Java 8中「System.out :: println」的用法
- 24. java println語句中+符號的含義
- 25. 問題與印刷,格式,println - java
- 26. Java的println插入額外的新行
- 27. Java:將一個數組傳遞給println
- 28. 的Java的println()打印字符
- 29. 什麼是系統的,在的println的System.out.println()在Java中
- 30. 這個Java println調用中的char轉換是做什麼的?
你想要兩個線程同時執行或線程1完成其運行後執行線程2嗎? –
線程1完成其運行後執行線程2 –
那麼爲什麼你需要兩個線程呢?線程背後的全部想法是同時運行代碼。 –