两个线程一个同步方法scjp

时间:2013-12-17 08:33:25

标签: java multithreading thread-safety scjp

为什么这封信的答案是? (下面的问答) 我理解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都是可能的。 (*)

3 个答案:

答案 0 :(得分:2)

这是正确的,因为有两个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个不同的结果。

答案 1 :(得分:0)

打印或记录不是同步的一部分。完整阅读本节: 它类似于问题: Inconsistency in output for Producer Consumer relationship program in Java

答案 2 :(得分:0)

您是否尝试过运行代码?

我做了,我得到了结果

9a 9b 10a 10b

我第二次

9a 10a 10b 9b

这意味着线程可以任意获取和释放锁。在真正发生之前,你无法预测执行顺序。

请注意,synchronized关键字保证一次只有一个线程访问代码块。