[英]Java Multithreading - What Really Happens When Accessing A “Locked” Object?
给定以下对象,并在包装器类中对其进行初始化:
// (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();
}
而且这也“同时”发生。
// (Thread 2 executes the following code also @ Runtime=1.0000000ms)
synchronized(requests) {
(requests.add(new Request());
}
据我了解,在这种情况下一定会发生以下情况:线程之一将成功锁定请求列表,执行其各自的任务,并在退出同步块时释放其锁定。
在我对“线程安全性”的理解中,这对我来说很奇怪。 可以说,尽管线程2试图做同样的事情,但线程1已经在请求列表上实现了锁定并首先进入了它的同步块。
1) 由于未实现对象的同步性而导致无法调用的同步块内部的代码发生了什么? (在这种情况下,使用线程2和该线程试图将其添加到列表中的新Request()-发生了什么?-该请求是否只是在欺骗并且从不添加到请求列表中,因为线程1已锁定宾语?
2) 线程2是否确实在等待线程1释放其锁定,并且在这种情况下,线程2重新查看了该对象并添加了请求? (假想的陷阱)如果是这种情况-如果线程1花60秒对列表中的所有Request对象执行handle()怎么办-导致线程2等待那60秒?
( 额外的问题 )关于Collections.synchronizedList的1&2的答案是否与ConcurrentHashMap的行为相同?
1)由于未实现对象的同步性而导致无法调用的同步块内部的代码发生了什么?
其他线程将被阻塞,直到已获取的线程释放了锁。 之后,保持线程释放锁,任何等待线程都可以获取它。 获得锁的一个可以继续进行,将不得不再次等待。
2)线程2是否确实在等待线程1释放其锁定,并且在这种情况下,线程2重新查看了该对象并添加了请求?
是的,线程2将必须等到线程1释放锁。 只有这样,它才能获取锁。
每个锁都有一个关联的监视器,用于监控谁可以访问与该锁关联的关键区域。 一次只有一个线程可以获取此监视器,并且可以访问关联的关键区域。 所有其他线程将不得不等待获取监视器。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.