我有多個線程打印數據。所有數據都打印出來;然而,他們不是爲了。含義線程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 –
那麼爲什麼你需要兩個線程呢?線程背後的全部想法是同時運行代碼。 –