![](/img/trans.png)
[英]Java copy file with reader and writer in different threads (Using BlockingQueue)
[英]How to implement a Reader/Writer program using threads?
我有一個閱讀器/編寫器實現的問題。 我應該編寫一個 Reader 類,該類從控制台獲取一個 String 並將其添加到一個 Queue 和一個 Writer 類,該類從同一隊列中刪除該字符串並使用線程將其輸出到控制台。 我只為一個字符串編寫了我的程序(鍵入一個字符串並通過隊列輸出該字符串),並且運行良好。 現在我正在努力實現它,以便我可以輸入多個字符串,按 Enter,然后 Reader 將其添加到隊列中,然后由 Writer 顯示它。 如果輸入 String quit
,則兩個線程都必須停止並且程序應該結束。
我的讀者想法是這樣的:
Scanner k = new Scanner(System.in);
in = k.nextLine();
if(in.equals("quit"))
System.exit(0);
synchronized(q){
while(!(in.equals("quit"))){
// System.out.println(q.isEmpty());
q.enqueue(in);
in = k.next();
if(in.equals("quit"))
System.exit(0);
}
}
我的 Writer 看起來像這樣:
public void run(){
synchronized(q){
while(!q.isEmpty()){
String out = q.dequeue();
System.out.println(out);
}
}
}
我的 Reader 似乎工作正常,因為我在添加到隊列后內置了Sys.out.(q.isEmpty)
。 它顯示隊列已滿,但 Writer 類沒有任何輸出到控制台。 寫入quit
停止程序沒有問題。
我不認為我完全理解線程。 我的主要方法只是使用Thread t1 = new Thread(new Reader(queue));
創建線程Thread t1 = new Thread(new Reader(queue));
和Writer
相同,然后啟動兩個線程。
synchronized(q){
while(!(in.equals("quit"))){
// System.out.println(q.isEmpty());
q.enqueue(in);
in = k.next();
if(in.equals("quit"))
System.exit(0);
}
}
這個同步塊太大了。 通常,您希望同步時間盡可能短。 進出。 同步的時間越長,其他線程被阻塞的時間就越長。
在同步時執行用戶輸入是禁忌。 不應阻塞其他線程,因為用戶打字速度較慢。
更糟糕的是,整個程序的循環都在同步塊中。 糟糕的讀者! 如此貪婪。 在用戶輸入所有輸入並鍵入“退出”之前,它不會放棄q
鎖。 只有這樣它才會釋放鎖並讓作者繼續。
while(!(in.equals("quit"))){
// System.out.println(q.isEmpty());
synchronized(q){
q.enqueue(in);
}
in = k.next();
if(in.equals("quit"))
System.exit(0);
}
作者有一個不同的致命缺陷。 一旦隊列為空,它就會退出。 但是,隊列在很多時候都是空的,不是嗎? 當它是作家不應該只是死。
一個快速的解決方法是將整個事情包裝在一個無限循環中:
public void run(){
while (true) {
synchronized(q){
while(!q.isEmpty()){
String out = q.dequeue();
System.out.println(out);
}
}
}
}
它會讓作家活着。 但它也會消耗 CPU 時間,循環數百萬次,而該死的用戶會慢慢啄擊鍵盤。 如果您檢查您的系統監視器,您會看到該程序的 CPU 使用率飆升至 100%。 不是很好。
解決這個問題有點超出本問答的范圍。 簡短的回答是使用wait() 和 notify()讓作者進入睡眠狀態,直到有可用的東西。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.