我已经开始深入学习线程,并在尝试理解我编写以下代码的概念的同时,我不确定代码的输出。以下是我编写的代码,public class UnsafeCheck extends Thread { private static Person person; // This method is not thread safe without synchronization. Make the method // synchronized to make the code thread safe. public synchronized Person getPerson() { if(person == null) { System.out.println("Inside if block"); person = new Person("Kilarapu Yethendra", 27); } return person; } public void run() { System.out.println("thread's run method"); getPerson(); } public static void main(String[] args) { UnsafeCheck uc = new UnsafeCheck(); uc.start(); UnsafeCheck uc1 = new UnsafeCheck(); uc1.start(); UnsafeCheck uc2 = new UnsafeCheck(); uc2.start(); } }输出:线程的运行方法内部 if 块线程的运行方法内部 if 块线程的运行方法内部 if 块如果我们观察到线程 uc 所做的输出更改并没有反映在线程 uc1 中,这就是为什么每个线程控制都转到 if 块的原因。我期望在 uc1 执行 run 方法时初始化 person 引用,但是对于 uc1 线程来说 person 仍然为空。我所做的一个更有趣的观察是,如果我将 getPerson() 方法设为静态,我将按预期获得输出。以下是 getPerson() 方法为静态时的输出。输出:线程的运行方法内部 if 块线程的运行方法线程的运行方法。请帮助我理解流程。
2 回答
函数式编程
TA贡献1807条经验 获得超9个赞
将您的方法声明为
public synchronized Person getPerson()
意味着它使用包含UnsafeCheck
实例(即this
)作为监视器来同步访问。当您创建三个不同的UnsafeCheck
实例时,每个实例都有自己的锁,并且代码不会按照您的预期执行。
和
public static synchronized Person getPerson()
使用的监视器对于所有实例都是相同的,即UnsafeCheck.class
,您会获得正确的static
Person
变量同步。
有关synchronized
方法的更多信息,请查看 Oracle 的教程:同步方法。
Cats萌萌
TA贡献1805条经验 获得超9个赞
好的,现在我知道你在做什么了,标题有误导性。监视器的同步关键字以对象方式锁定它,因此只有一个线程可以进入方法 PER Object。
你可以做两件事来让它广泛应用:
1.使 getPerson 方法静态(它将在应用程序范围内同步)
2.使用同步块,允许您选择同步对象(通常“this”用于对象同步,“UnsafeCheck.class”用于应用程序范围)
添加回答
举报
0/150
提交
取消