在阅读有关线程中的并发问题并通过synchronized
关键字处理它时,我想到的问题是,当我们使用术语lock
时,它用于包含{的对象{1}}方法(或线程的工作)。但是为什么我们不能将术语run
用于仅包含lock
关键字的方法,因为此关键字表示一旦线程进入该方法,那么这个线程只能在方法完成后被JVM调度程序干扰?
我正在从第一个java开始学习,并且那里写着“对象被锁定”的行,并且给出的理由再次以质疑的方式,即“如果我们有两个同步方法会发生什么”。所以我我在这里混淆,如果只锁定方法会发生什么令人惊讶的事情?
如果我提出一个模糊的问题并提前致谢,请原谅我。
答案 0 :(得分:8)
同步时,线程获取object monitor
。由于一次只能有一个线程获取监视器,因此另一个尝试获取它的线程将被阻塞。所以从某种意义上说,除了某段代码之外,没有什么是真正的locked
。
答案 1 :(得分:3)
使用synchronized关键字隐含等效于使用ReentrantLock,因为javadoc在示例中显示它:
class X {
private final ReentrantLock lock = new ReentrantLock();
// ...
public void m() {
lock.lock(); // block until condition holds
try {
// ... method body
} finally {
lock.unlock()
}
}
}
我不知道它是否能回答你的问题,也许我应该让juste做出评论。
答案 2 :(得分:1)
解决您的问题:如果我们有两种同步方法会发生什么?
请考虑以下代码段: -
public class Worker {
private Object lock1 = new Object();
private Object lock2 = new Object();
public void step1() {
synchronized (lock1) {
//do something
}
}
public void step2() {
synchronized (lock2) {
//do something
}
}
public void process() {
step1();
step2();
}
public void main() {
long start = System.currentTimeMillis();
Thread t1 = new Thread(new Runnable() {
public void run() {
process();
}
});
t1.start();
Thread t2 = new Thread(new Runnable() {
public void run() {
process();
}
});
t2.start();
t1.join();
t2.join();
long end = System.currentTimeMillis();
System.out.println("time taken " + (end - start));
}
}
在这段代码中,我们使用lock1和lock2作为对象锁,但是如果我们使用这个关键字而不是这些锁(lock1和lock2)会发生什么?
由于在两个同步块中使用相同的对象锁定,因此产生了这种时间差。如果thread-1将访问step1方法,则step2方法将被阻塞为thread-2。 如果方法具有独立性,则应使用不同的锁。