[英]threads synchronization issue
假設我有3個類:1.僅包含一個整數的存儲。 2.計數器,其中包含一個線程,該線程負責計數(0,1,..,k),並將循環索引的每次迭代存儲在Storage類中。 3.Printer包含一個線程,該線程負責讀取Storage類中的值並進行打印。
現在我必須創建一個主類,該主類將創建運行Counter和Printer線程的這3個對象,並且from(0,1,..,k)中的每個數字都必須僅按正確的順序打印一次。
我該如何同步對Storage類的訪問,因此首先我將一個數字放入帶有Counter的Storage中,而不是使用Printer類進行打印?
到目前為止,這是我寫的內容:
public class Storage {
private int num;
public Storage(){
}
public synchronized void setNum(int num){
this.num = num;
}
public synchronized int getNum(){
return num;
}
public class Counter implements Runnable {
Storage s;
public Counter(Storage t){
s = t;
}
@Override
public void run() {
int i = 0;
while(true){
s.setNum(i++);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public class Printer implements Runnable {
Storage s;
public Printer(Storage s){
this.s= s;
}
@Override
public void run() {
while(true){
System.out.println(s.getNum());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public class mainProg {
public static void main(String[] args){
Storage s = new Storage();
Counter c = new Counter(s);
Printer p = new Printer(s);
Thread c1 = new Thread(c);
Thread p2 = new Thread(p);
c1.start();
p2.start();
}
}
編輯:我找到了解決方案,這是:
public class Storage {
private int num;
private boolean available = false;
public Storage(){
}
public synchronized void setNum(int num){
while(available){
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
available = true;
notifyAll();
this.num = num;
}
public synchronized int getNum(){
while(!available){
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
available = false;
notifyAll();
return num;
}
}
這種方法行不通,因為不能保證在Counter
的每個周期中都會在並行線程中執行Printer
的周期。 您需要能夠在Storage
存儲多個值。 您可以在此處使用BlockingQueue
,然后像這樣重寫Storage
類:
public class Storage {
private BlockingQueue<Integer> numbers = new LinkedBlockingQueue<Integer>();
public void setNum(int num) {
try {
this.numbers.put(num);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
public int getNum() {
try {
return numbers.take();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
請注意,如果BlockingQueue
為空並且Printer
要獲取新值,則它將等待隊列中出現新元素。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.