Java中使用synchronized关键字实现简单同步操作示例
程序员文章站
2024-03-02 18:05:34
简单记录下java中synchronized关键字的使用方法。
在介绍之前需要明确下java中的每一个类的对象实例都有且只有一个锁(lock)和之相关联,synchron...
简单记录下java中synchronized关键字的使用方法。
在介绍之前需要明确下java中的每一个类的对象实例都有且只有一个锁(lock)和之相关联,synchronized关键字只作用于该锁,即可以认为synchronized只对java类的对象实例起作用。
synchronized修饰函数
复制代码 代码如下:
public synchronized amethod(){
}
这就是最常用的情景,那么这个同步方法的用途是啥,为了方便就记作amethod方法。
1、synchronized锁定的是调用这个同步方法的对象实例,举个例子,同一个实例p1在不同线程中都调用amethod时会产生同步;
2、需要注意的是这个对象所属的类的另一对象p2却能够任意调用这个amethod,因为不同的对象实例的synchronized方法是不相干扰的。也就是说,其它线程照样可以同时访问相同类的另一个对象实例中的amethod方法;
3、如果一个对象有多个synchronized方法,比如amethod、bmethod、cmethod,现在只要一个线程访问了其中的一个synchronized方法,其它线程不能同时访问这个对象中任何一个synchronized方法。
上述代码其实等价于下面:
复制代码 代码如下:
public void amethod() {
synchronized (this) {
}
}
这里的this就是指的该实例对象的引用,如p1。可见同步方法实质是将synchronized作用于object reference。那个拿到了p1对象锁的线程,才能够调用p1的同步方法,而对p2而言,p1这个锁和他毫不相干,程序也可能在这种情形下摆脱同步机制的控制,造成数据混乱。由此我们引出了下面的同步块。
synchronized修饰代码块
复制代码 代码如下:
public void dmethod(someobject so) {
synchronized(so) {
}
}
在这里synchronized获得锁就是so这个对象的锁,因而谁拿到这个锁谁就能够运行他所控制的那段代码。当有一个明确的对象作为锁时,就能够这样写程式,但当没有明确的对象作为锁,只是想让一段代码同步时,能够创建一个特别的instance变量(他得是个对象)来充当锁:
复制代码 代码如下:
class foo implements runnable {
private byte[] lock = new byte[0];
public void method() {
synchronized(lock) {
}
}
}
零长度的byte数组对象创建起来将比任何对象都经济高效。
synchronized修饰静态方法
前面提到了synchronized关键字只对不同线程中的p1实例有效,那如何可以同时对p1和p2不同实例有效呢,答案就是使用synchronized修饰静态方法,类的静态方法可以说是这个类自有的,并不依赖类的实例,所以我们只要对类的静态方法使用synchronized关键字来修饰就可以达到不同实例间的同步了。
上一篇: Java变量和对象的作用域