gpt4 book ai didi

java - 这是在 Java 中错误使用内部条件队列吗?

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:57:51 25 4
gpt4 key购买 nike

此程序尝试按顺序打印数字 1 到 10,第一个线程打印奇数,第二个线程打印偶数。

我一直在阅读 JCIP 的书,它说:

Ensure that the state variables making up the condition predicate are guarded by the lock associated with the condition queue.

在下面的程序中,条件队列将对应静态成员'obj1',而组成条件谓词的状态变量是静态volatile成员'count'。 (如果我对条件、状态变量、条件谓词的解释有误,请告诉我)

下面的程序可以正常工作,但显然违反了上面的习惯用法。我是否正确理解了作者的意思?下面的代码真的是一个糟糕的编程实践吗(恰好可以正常工作)

你能举个例子吗?如果不遵循上述习语,我会遇到问题吗?

public class OddEvenSynchronized implements Runnable {
static Object obj1 = new Object(); // monitor to share data
static volatile int count =1; // condition predicate
boolean isEven;
public OddEvenSynchronized(boolean isEven) { //constructor
this.isEven=isEven;
}
public void run (){
while (count<=10){
if (this.isEven == true){
printEven(); //print an even number
}
else{
printOdd(); //print an odd number
}
}
}

public static void main(String[] args) {
Thread t1 = new Thread (new OddEvenSynchronized(true));
Thread t2 = new Thread (new OddEvenSynchronized(false));
//start the 2 threads
t1.start();
t2.start();
}

void printEven(){
synchronized (obj1) {
while (count%2 != 0){
try{
obj1.wait();
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}
System.out.println("Even"+count);

count++; //unguarded increment (violation)
synchronized (obj1) {
obj1.notifyAll();
}
} //end method
void printOdd(){
synchronized (obj1) {
while (count%2 == 0){
try{
obj1.wait();
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}
System.out.println("Odd"+count);
count++; //unguarded increment (violation)
synchronized (obj1) {
obj1.notifyAll();
}

} //end method
} //end class

最佳答案

如果您未在 obj1 上同步,请不要读取或写入 count。那是不行不行!打印和增量应该在同步块(synchronized block)内完成。

synchronized (obj1) {
while (count%2 != 0){
try {
obj1.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Even"+count);
}

synchronized (obj1) {
count++;
obj1.notifyAll();
}

您会注意到现在没有理由放弃同步。合并这两个 block 。

synchronized (obj1) {
while (count%2 != 0){
try {
obj1.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

System.out.println("Even"+count);
count++;
obj1.notifyAll();
}

The below program works correctly but is clearly violating the above idiom.

多线程编程的潜在危险在于,有缺陷的程序可能看起来大部分时间都能正常工作。竞争条件可能非常曲折,因为它们通常需要非常严格的时间条件,而这种情况很少发生。

严格遵守规则真的非常重要。正确地进行多线程编程非常困难。几乎可以肯定的是,只要您偏离规则并试图变得聪明,就会引入细微的错误。

关于java - 这是在 Java 中错误使用内部条件队列吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32280646/

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