Abh*_*hav 5 java multithreading synchronization
代码段 - 1
class RequestObject implements Runnable
{
private static Integer nRequests = 0;
@Override
public void run()
{
synchronized (nRequests)
{
nRequests++;
}
}
}
Run Code Online (Sandbox Code Playgroud)
代码段 - 2
class RequestObject implements Runnable
{
private static Integer nRequests = 0;
private static Object lock = new Object();
@Override
public void run()
{
synchronized (lock)
{
nRequests++;
}
}
}
Run Code Online (Sandbox Code Playgroud)
虽然第二个代码片段工作正常而没有引起任何竞争条件,但第一个代码片段不能成功同步对同一个类的不同实例(RequestObject)之间的静态数据成员的访问.有人可以对此有所了解吗?我想了解为什么第一种方法不起作用.
我最初的实现是第一个.后来我在/sf/answers/148428661/中看到了.
您不断创建新的Integer对象,然后对其进行同步,这至少会让人难以理解.所以你可以得到以下场景:
线程A获取当前值nRequests(假设为0)
线程B队列为相同的值(0)
线程A增加nRequests(值1)
线程C获取新值并在其上同步,增加它并释放值.
线程A放开监视器0
线程B在0上同步并将其增加到1,覆盖C的变化
使用第二种方法,您可以拥有一个每个人都必须同步的对象.这正是你想要的.
的实例Integer是不可变的,nRequests++因此创建一个新Integer对象来保存结果,并将其存储在nRequests. 该synchronized语句在对象上同步。因此,线程将在不同的对象上同步。是的,同一个对象上的同步块中可能只有一个线程同时存在,但是不同的线程可能同时在不同对象的同步块中......
同步访问静态状态的最简单方法是将其放入静态同步方法中:
static synchronized void increment() {
nRequests++;
}
Run Code Online (Sandbox Code Playgroud)
这等效于以下同步块:
synchronized (RequestObject.class) {
nRequests++;
}
Run Code Online (Sandbox Code Playgroud)
其中 RequestObject 是包含静态字段的类。
| 归档时间: |
|
| 查看次数: |
432 次 |
| 最近记录: |