gpt4 book ai didi

java - 线程同步问题

转载 作者:行者123 更新时间:2023-11-30 07:37:20 24 4
gpt4 key购买 nike

假设我有 3 门课:1. 只包含一个整数的存储。2. Counter,其中包含一个负责计数 (0,1,..,k) 的线程,并将循环索引的每次迭代存储在 Storage 类中。3.Printer,其中包含一个线程,负责读取Storage类中的值并打印它。

现在我必须创建一个主类,它创建这3个对象,运行 Counter 和 Printer 的线程,并且(0,1,..,k)中的每个数字都必须以正确的顺序打印一次。

我如何同步对我的存储类的访问,首先我将一个数字放入带有计数器的存储中,然后使用我的打印机类打印它?

这是我到目前为止所写的内容:

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 的周期。您需要能够在存储中存储多个值。您可以在此处使用 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想要获取新值,它将等待队列中出现新元素。

关于java - 线程同步问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35204480/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com