欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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关键字来修饰就可以达到不同实例间的同步了。