use block-level synchronization with private variable of non-primitive type

 

What is the significance of parameter passed to synchronized?


synchronized ( parameter )
{

}

to achieve block level synchronization. Somewhere i saw code like


class test
{
    public static final int lock =1;

    ...

    synchronized(lock){
       ...
    }
}

I don't understand the purpose of this code.

Can anyone give me a better example and/or explain it?

First answer:

It's the reference to lock on. Basically two threads won't execute blocks of code synchronized using the same reference at the same time. As Cletus says, a synchronized method is mostly equivalent to using synchronized (this) inside the method.

I very much hope that the example code you saw wasn't quite like that - you're trying to synchronize on a primitive variable. Synchronization only works on a monitor (via a reference) - even if it were legal code, x would be boxed, which would lead to some very odd behaviour, as some integers will always be boxed to the same references, and others will create a new object each time you box. Fortunately, the Java compiler realises this is a very bad idea, and will give you a compile-time error for the code you've posted.

More reasonable code is:


class Test
{
    private static final Object lock = new Object();

    ...

    synchronized(lock){
       ...
    }
}

I've made the lock private, and changes its type to Object. Whether or not it should be static depends on the situation - basically a static variable is usually used if you want to access/change static data from multiple threads; instance variables are usually used for locks when you want to access/change per-instance data from multiple threads.

 

Second answer:

This:


public synchronized void blah() {
  // do stuff
}

is semantically equivalent to:


public void blah() {
  synchronized (this) {
    // do stuff
  }
}

Some people don't like to use 'this' for synchronization, partly because it's public (in that the instance is visible to external code). That's why you end up with people using private locks:


public class Foo
  private final static String LOCK = new String("LOCK");

  public void blah() {
    synchronized (LOCK) {
      // do stuff
    }
  }
}

The benefit is that LOCK is not visible outside the class plus you can create several locks to deal with more fine-grained locking situations.

  1. synchronized代码块不能修饰基本数据类型的变量
  2. synchronized代码块修饰基本数据类型的包装类时,如果在同步块中对同步变量进行运算会导致同步失效, 因为内部包含了封箱拆箱动作,包装类引用指向了新的对象
  3. synchronized代码块修饰String变量时,如果在同步块中对String变量重新赋值会导致同步失效, 因为创建String的实例并不需要new,String变量在重新赋值时引用指向了新的对象
  4. synchronized(this):相当于修饰普通方法
  5. synchronized(A.class):相当于修饰static方法

参考:Block level synchronization-stackoverflow

synchronized关键字解析

========================

 

There are several ways to synchronize access to a static variable.

  1. Use a synchronized static method. This synchronizes on the class object.

    public class Test {
        private static int count = 0;
    
        public static synchronized void incrementCount() {
            count++;
        }
    } 
    
  2. Explicitly synchronize on the class object.

    public class Test {
        private static int count = 0;
    
        public void incrementCount() {
            synchronized (Test.class) {
                count++;
            }
        }
    } 
    
  3. Synchronize on some other static object.

    public class Test {
        private static int count = 0;
        private static final Object countLock = new Object();
    
        public void incrementCount() {
            synchronized (countLock) {
                count++;
            }
        }
    } 
    

Method 3 is the best in many cases because the lock object is not exposed outside of your class.

转载自:How to synchronize a static variable among threads running different instances of a class in Java?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值