我正在编写一个程序来测试线程如何在另一个线程已获得对同一对象的锁定的情况下保持等待,但是在查看输出后,我不确定锁定在Java中如何工作。这是我写的:
timeit.timeit(p1,setup=up, number=100) 0.3046940103986765 3rd
timeit.timeit(p2,setup=up, number=100) 0.33943337437485366 4th
timeit.timeit(p3,setup=up, number=100) 0.2795306502784811 1st
timeit.timeit(p4,setup=up, number=100) 0.29027710723995326 2nd
}
我希望线程t2永远等待着,程序只会打印
在A内,t1
但是当我运行程序时,我得到以下输出:
在A内,t1
在A内,t2
任何人都可以解释这里发生了什么吗?
答案 0 :(得分:4)
我正在编写一个程序来测试线程如何保持等待,如果 另一个线程已获得对同一对象的锁定
单把锁在这里:
synchronized void methodA() {
System.out.println("inside A , " + Thread.currentThread().getName());
}
它获取当前实例的锁,但是代码中没有语句以线程可以永远等待锁的方式锁。
看看我的评论:
@Override
public void run() {
while (true) {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// the lock is set here
methodA();
// and that is released here
}
}
使同步方法永不释放锁,只有一个线程可以输入:
synchronized void methodA() {
while (true) {
System.out.println("inside A , " + Thread.currentThread()
.getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// handle it
}
}
}
打印:
在A内,t1
在A内,t1
在A内,t1
...
还有其他一些与线程一起玩的例子。
将sleep()
替换为wait()
,当前线程将释放该锁:
synchronized void methodA() {
while (true) {
System.out.println("inside A , " + Thread.currentThread()
.getName());
try {
wait();
} catch (InterruptedException e) {
// handle it
}
}
}
打印:
在A内,t1
在A内,t2
使用notify()
(通知正在等待的线程)和wait()
(使当前线程等待并释放锁,如果有的话)使它们之间的线程协作:
synchronized void methodA() {
while (true) {
notify();
System.out.println("inside A , " + Thread.currentThread()
.getName());
try {
wait();
} catch (InterruptedException e) {
// handle it
}
}
}
打印:
在A内,t1
在A内,t2
在A内,t1
在A内,t2
...
答案 1 :(得分:0)
这是预期的情况。
您的t1线程正在其他线程而不是主线程中等待。
在您的主线程(创建线程并调用start())中,仅等待5秒钟并启动线程2
仅当线程1永远调用该方法时,您的同步方法才进行同步。
线程1调用同步化方法并返回后,线程1停止5秒。
那时,thread2可以使用该方法。
答案 2 :(得分:0)
方法前面的关键字synchronized
表示该方法不能被两个线程同时调用。
一个线程调用该方法后,其他试图调用该方法的线程将被阻塞,直到第一个线程从该方法返回为止。然后,其他调用相同方法的线程可以自动继续进行调用(一次一个)。
答案 3 :(得分:0)
您使用synchronized
进行的隐式锁定的工作时间很短-即释放锁定后的println
。您的两个线程都在争抢在那里的锁。
将代码更改为此,您将看到想要的行为
class MyThread implements Runnable {
@Override
public void run() {
methodA();
}
}
synchronized void methodA() {
while(true)
System.out.println("inside A , " + Thread.currentThread().getName());
}