Java 多线程 - 访问 "Locked" 对象时究竟发生了什么?
Java Multithreading - What Really Happens When Accessing A "Locked" Object?
假设在包装器中定义并初始化了以下对象 class:
// (thread-safe) List of Requests made by users
private static List<Request> requests = Collections.synchronizedList(new ArrayList<Request>());
在更新循环中不断调用以下代码:
// <-- (Thread 1 executes the following code @ Runtime=1.0000000ms)
synchronized(requests) {
for (Request request : requests)
request.handle();
requests.clear();
}
这也会发生"simultaneously"。
// (Thread 2 executes the following code also @ Runtime=1.0000000ms)
synchronized(requests) {
(requests.add(new Request());
}
据我了解,在这种情况下肯定会发生以下情况:其中一个线程将成功锁定请求列表,执行其各自的任务,并在退出同步块时释放其锁定。
根据我对 "thread-safety" 的理解,这就是让我感到奇怪的地方。假设线程 1 已获得对请求列表的锁定并首先进入其同步块,尽管线程 2 试图执行相同操作。
1) 由于未实现对象的同步性而无法调用的同步块内部代码会发生什么?(在本例中,使用线程 2以及该线程试图添加到列表中的新 Request() - 它发生了什么? - 请求只是 poof 并且从未添加到请求列表中,因为线程 1 有锁定了对象?
2) 线程 2 是否真的在等待线程 1 释放它的锁,并且在发生这种情况时线程 2 重新查看对象并添加请求?(假设的陷阱) 如果是这种情况 - 如果线程 1 需要 60 秒来对列表中的所有请求对象执行 handle() - 导致线程 2 等待这 60 秒怎么办?
(奖金问题) 1&2 关于 Collections.synchronizedList 的答案是否遵循与 ConcurrentHashMap 相同的行为?
1) What happens to the code inside of a synchronous block that cannot be called due to the synchronicity of an object not being achieved?
其他线程将被阻塞,直到获得锁的线程释放锁。之后,持有线程释放锁,任何等待线程都可以获取它。获得锁的可以继续进行其他的将不得不再次等待。
2) Is Thread 2 literally waiting for Thread 1 to release its lock and upon that happening Thread 2 gets a fresh look at the object and adds the request?
是,线程 2 必须等到线程 1 释放锁。只有这样它才能获得锁。
每个锁都有一个关联的监视器,用于控制谁可以访问与锁关联的关键区域。一次只有一个线程可以获得此监视器并可以访问关联的临界区。所有其他线程将不得不等待获取监视器。
假设在包装器中定义并初始化了以下对象 class:
// (thread-safe) List of Requests made by users
private static List<Request> requests = Collections.synchronizedList(new ArrayList<Request>());
在更新循环中不断调用以下代码:
// <-- (Thread 1 executes the following code @ Runtime=1.0000000ms)
synchronized(requests) {
for (Request request : requests)
request.handle();
requests.clear();
}
这也会发生"simultaneously"。
// (Thread 2 executes the following code also @ Runtime=1.0000000ms)
synchronized(requests) {
(requests.add(new Request());
}
据我了解,在这种情况下肯定会发生以下情况:其中一个线程将成功锁定请求列表,执行其各自的任务,并在退出同步块时释放其锁定。
根据我对 "thread-safety" 的理解,这就是让我感到奇怪的地方。假设线程 1 已获得对请求列表的锁定并首先进入其同步块,尽管线程 2 试图执行相同操作。
1) 由于未实现对象的同步性而无法调用的同步块内部代码会发生什么?(在本例中,使用线程 2以及该线程试图添加到列表中的新 Request() - 它发生了什么? - 请求只是 poof 并且从未添加到请求列表中,因为线程 1 有锁定了对象?
2) 线程 2 是否真的在等待线程 1 释放它的锁,并且在发生这种情况时线程 2 重新查看对象并添加请求?(假设的陷阱) 如果是这种情况 - 如果线程 1 需要 60 秒来对列表中的所有请求对象执行 handle() - 导致线程 2 等待这 60 秒怎么办?
(奖金问题) 1&2 关于 Collections.synchronizedList 的答案是否遵循与 ConcurrentHashMap 相同的行为?
1) What happens to the code inside of a synchronous block that cannot be called due to the synchronicity of an object not being achieved?
其他线程将被阻塞,直到获得锁的线程释放锁。之后,持有线程释放锁,任何等待线程都可以获取它。获得锁的可以继续进行其他的将不得不再次等待。
2) Is Thread 2 literally waiting for Thread 1 to release its lock and upon that happening Thread 2 gets a fresh look at the object and adds the request?
是,线程 2 必须等到线程 1 释放锁。只有这样它才能获得锁。
每个锁都有一个关联的监视器,用于控制谁可以访问与锁关联的关键区域。一次只有一个线程可以获得此监视器并可以访问关联的临界区。所有其他线程将不得不等待获取监视器。