下面的代码是 Java 中传递接力棒程序的一部分:
主 P1(写入器) P2(写入器) P3(读取器) P4(读取器)
主要的();
package ReadersPreference;
import java.util.concurrent.Semaphore;
/**
* * @author me
*/
public class Main {
public static void main(String[] args) {
AnyData x = new AnyData(5.7);//gives writers something to write,
//readers something to read
Semaphore e = new Semaphore(1);//control entry
Semaphore r = new Semaphore(0);//used to delay readers
Semaphore w = new Semaphore(0);//used to delay writers
int nr = 0;//readers active
int nw = 0;//writers active
int dr = 0;//readers waiting
int dw = 0;//writers waiting
P1 r1 = new P1(e, r, w, x, nr, nw, dr, dw); // #reader thread 1
P2 r2 = new P2(e, r, w, x, nr, nw, dr, dw); // #reader thread 2
P5 r3 = new P5(e, r, w, x, nr, nw, dr, dw); // #reader thread 3
P6 r4 = new P6(e, r, w, x, nr, nw, dr, dw); // #reader thread 4
P3 w1 = new P3(e, r, w, x, nr, nw, dr, dw); // #writer thread 1
P4 w2 = new P4(e, r, w, x, nr, nw, dr, dw); // #writer thread 2
System.out.println("threads commanded to start");
r1.start(); // calls run() method in Thread
r2.start();
r3.start();
r4.start();
w1.start();
w2.start();
}//end of main
}//end of class
读者进程
package ReadersPreference;
import java.util.concurrent.Semaphore;
public class P1 extends Thread {
private Semaphore e;
private Semaphore r;
private Semaphore w;
private AnyData pillarbox;
private int nw;
private int nr;
private int dr;
private int dw;
public P1(Semaphore e, Semaphore r, Semaphore w, AnyData pbox,
int nw, int nr, int dr, int dw) {
this.nw = nw;
this.nr = nr;
this.dr = dr;
this.dw = dw;
this.e = e;
this.r = r;
this.w = w;
pillarbox = pbox;
}// end of constructor
public void run() {
PERFORM OPERATIONS
}// end of run method
}// end of class
现在,根据我的输出,它似乎可以工作。然而,我的讲师指出了两个主要缺陷。一种是计数器 (nr,nw,dr,dw) 通过值而不是通过引用传递。这意味着每个线程检查自己的数据副本而不是使用共享变量,这会阻止程序按应有的方式运行。
我一直在阅读大量关于传递值和参考的内容,起初我觉得我的头很肿,我想我现在明白了大部分,但我仍然没有看到解决方案。我可以理解为什么信号量可以工作,因为它们已经是一个引用(而不是它们被传递的值是一个引用)。我不知道计数器的问题到底出在哪里,也不知道如何解决它。
当他说线程时,他指的是进程类(构造函数/算法)还是主类中的实例化,还是两者兼而有之?
基于将原语共享为对象的阅读,我提出的最接近解决方案的解决方案如下:
public void setCounters(int nr){nr = newNR;}
再次,虽然我对如何实现它含糊不清
第二个可能的主要缺陷是我创建了几个进程类文件并将每个文件作为一个线程运行,而不是编写两个(读取器/写入器)并根据需要使用尽可能多的对象。我很模糊这意味着什么,而且,考虑到我的输出打印语句对于每个进程都是唯一的,在输出中唯一地标识每个以进行验证,为什么这种方法在出于某种目的而被认为是缺陷时,确实它会影响读者/作者的解决方案吗?