java - 两个线程一个同步方法scjp

标签 java multithreading thread-safety scjp

为什么这个字母的答案是b? (下面有问题和答案) 我理解 7a 7b 8a 8b,因为该方法是同步的,因此一次只能执行一个线程,但为什么 6a 7a 6b 7b 也可以接受?第二个线程不应该等待第一个线程完成该方法吗?

public class Lockdown implements Runnable {
           public static void main(String[] args) {
             new Thread(new Lockdown()).start();
             new Thread(new Lockdown()).start();
           }
           public void run() { locked(Thread.currentThread().getId()); }
           synchronized void locked(long id) {
             System.out.print(id + "a ");
             System.out.print(id + "b ");
           }
         }

b) 组 7a 7b 8a 8b 和组 6a 7a 6b 7b 都是可能的。 (*)

最佳答案

这是正确的,因为有两个 Lockdown 对象,每个对象都有一个线程。例如

Lockdown lockk = new Lockdown();
new Thread(lockk).start();  //thread1
new Thread(lockk).start();  //thread2

会导致线程等待第一个完成执行。所以结果总是7a 7b 8a 8b,或者类似的东西。仅当线程在同一对象上运行时,同步方法才会使线程等待。

但是当线程在不同的对象上运行时,它也可能输出6a 7a 6b 7b。你的例子就像

Lockdown lock1 = new Lockdown();
Lockdown lock2 = new Lockdown();
new Thread(lock1).start();  //thread1
new Thread(lock2).start();  //thread2

输出:

thread1 on lock1 print -> 6a
thread2 on lock2 print -> 7a
thread1 on lock1 print -> 6b
thread2 on lock2 print -> 7b

但也可以是:

thread1 on lock1 print -> 6a
thread1 on lock1 print -> 6b
thread2 on lock2 print -> 7a
thread2 on lock2 print -> 7b

因此您可以获得 2 个不同的结果。

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

相关文章:

java - 两个线程使用同一对象但修改该对象的单独属性

AuthorizeAttribute 上的 C# 线程安全 CreateIdentityAsync

c++ - 线程内的虚拟调用忽略派生类

Java Map<String, Map<String, Object>> 转换为 String 并返回

java - Android - Java - 在代码中使用的预定义 XML 模板

java - ElasticSearch 中的嵌套搜索不起作用?

java - 如何将带有 '/' 符号的值作为获取参数传递给我的 Controller ?

swift - CloudKit 错误处理 - 重试逻辑

java - Thread.stop() 的后果

android - 等到 fragment 被添加到 UI