簡體   English   中英

線程同步問題

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM