gpt4 book ai didi

Java Synchronized 将一个类的所有同步方法相互同步?

转载 作者:行者123 更新时间:2023-12-04 03:37:33 26 4
gpt4 key购买 nike

我有一个关于 java 同步的问题。在下面的 Java 程序中,我没有得到任何输出。但是,如果我从方法 IFoo.s() 中删除同步语句,我将得到一些输出。似乎方法 IFoo.setP() 和 IFoo.s() 彼此同步。但是'synchronized'应该只是防止两个线程同时调用synchronized方法吧?

package com.example.relectiontest;

import java.awt.Point;
import java.util.Random;

public class Main {

public static void main(String[] args) throws Exception{
final IFoo f = new IFoo();
Runnable r = new Runnable() {
public void run() {
Random r = new Random();
int a = r.nextInt(5)+1;
for(int i=0;i<1000000;++i){
f.setP(a);
}
}
};
Runnable r2 = new Runnable() {
public void run() {
for(int i=0;i<1000000;++i){
f.s();
}
}
};
Thread T1 = new Thread(r, "T1");
Thread T2 = new Thread(r, "T2");
Thread T3 = new Thread(r2, "T3");
T3.start();
T1.start();
T2.start();
}

private static class IFoo{
private Point p = new Point();

public synchronized void setP(int a){
//System.out.println("p1 "+Thread.currentThread());
p.x = a;
p.y = p.x;
int x = p.x , y = p.y;
if(x != y)
System.out.println(Thread.currentThread()+"\t"+x+" "+y);
//System.out.println("p2 "+Thread.currentThread());
}

public synchronized void s(){
//System.out.println("s");
p.x = 0;
}
}
}

那么,为什么我看不到任何输出?

问候

最佳答案

因为同步 x != y 永远不会为真。

在你的非同步版本中,s() 有机会每隔一段时间将 p.x 设置为 0(即使它没有正确同步)。

在同步版本中,s() 必须等到 setP 完成(因为它们都是同步的,共享隐式的 this 锁), 由于 setP 中的逻辑,条件不可能为真。

您的示例过于复杂。您可以按如下方式写出来(在两种方法上都添加 synchronized 以查看不会打印任何内容):

private static class IFoo {
volatile int x = 0;
public void setP(int a) {
x = a;
if(x != a)
System.out.println("Someone changed x!");
}

public void s() {
x = 0;
}
}

另请注意,静态同步方法在 Class 对象上进行同步,因为它们没有 this。因此,实例和静态方法不会相互锁定,除非您在公共(public)锁上显式同步。

关于Java Synchronized 将一个类的所有同步方法相互同步?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32117779/

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