同步块在获取所需对象的锁定时未按预期工作,但在应用于 'this' 时工作正常
Syncronization block not working as expected, when aquired lock on required object, but works fine when applied on 'this'
public class SyncBlockIssue {
public static void main(String[] args) {
Thread r1= new Multi();
Thread t1= new Thread(r1);
Thread t2= new Thread(r1);
t1.start();
t2.start();
}
}
class Multi extends Thread
{
Integer count =new Integer(0);
@Override
public void run() {
for(int i=0;i<100000;i++)
{
synchronized (count) {
//synchronized (this) { //working fine with this
count++;
}
}
System.out.println(Thread.currentThread().getName() + " "+count);
}
}
上面的代码是从第 2 个线程打印 200 万,无论我 运行 在 'this' 上获取锁时多少次,但是当获取锁 'count' 时打印任意计数] 目的。
谁能解释一下区别。
这是我的猜测,因为我不能使用注释来输入这么多单词。
Integer
对象是不可变的:
/**
* The value of the {@code Integer}.
*
* @serial
*/
private final int value;
/**
* Constructs a newly allocated {@code Integer} object that
* represents the specified {@code int} value.
*
* @param value the value to be represented by the
* {@code Integer} object.
*/
public Integer(int value) {
this.value = value;
}
因此,当您执行 count++
时,将创建一个新的 Integer
对象。 count
引用然后指向新对象。
假设流程如下:
Thread r1
获取count
锁(注意count object
被锁),此时thread r2
被阻塞。
r1
调用 count++
,创建一个新的 Integer
对象。 count
引用然后指向新对象。并且r1
释放锁。(这个锁是指前面的Integer对象)。
被阻塞的r2
获取锁
r1
也获得了锁,因为count
已经指向了一个新的对象。
两个线程都执行count++
:出现问题。
以下代码证明两个线程同时持有“锁”
for(int i=0; i<2; i++)
{
synchronized (count) {
System.out.println(Thread.currentThread().getName() + "get lock");
count++;
if (i == 1) {
try {
Thread.sleep(100000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + "release lock");
}
}
public class SyncBlockIssue {
public static void main(String[] args) {
Thread r1= new Multi();
Thread t1= new Thread(r1);
Thread t2= new Thread(r1);
t1.start();
t2.start();
}
}
class Multi extends Thread
{
Integer count =new Integer(0);
@Override
public void run() {
for(int i=0;i<100000;i++)
{
synchronized (count) {
//synchronized (this) { //working fine with this
count++;
}
}
System.out.println(Thread.currentThread().getName() + " "+count);
}
}
上面的代码是从第 2 个线程打印 200 万,无论我 运行 在 'this' 上获取锁时多少次,但是当获取锁 'count' 时打印任意计数] 目的。 谁能解释一下区别。
这是我的猜测,因为我不能使用注释来输入这么多单词。
Integer
对象是不可变的:
/**
* The value of the {@code Integer}.
*
* @serial
*/
private final int value;
/**
* Constructs a newly allocated {@code Integer} object that
* represents the specified {@code int} value.
*
* @param value the value to be represented by the
* {@code Integer} object.
*/
public Integer(int value) {
this.value = value;
}
因此,当您执行 count++
时,将创建一个新的 Integer
对象。 count
引用然后指向新对象。
假设流程如下:
Thread r1
获取count
锁(注意count object
被锁),此时thread r2
被阻塞。r1
调用count++
,创建一个新的Integer
对象。count
引用然后指向新对象。并且r1
释放锁。(这个锁是指前面的Integer对象)。
被阻塞的r2
获取锁r1
也获得了锁,因为count
已经指向了一个新的对象。两个线程都执行
count++
:出现问题。
以下代码证明两个线程同时持有“锁”
for(int i=0; i<2; i++)
{
synchronized (count) {
System.out.println(Thread.currentThread().getName() + "get lock");
count++;
if (i == 1) {
try {
Thread.sleep(100000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + "release lock");
}
}