9.synchronized 是个啥东西?应该怎么使用?

简介: 9.synchronized 是个啥东西?应该怎么使用?

synchronized 是什么?

老王:小陈,从今天开始我们就要进入synchronized的讨论了;首先小陈你来讲讲对synchronized的理解

小陈:synchronized啊,我理解就是一个JDK提供的同步的关键字,通过synchronized可以锁定一个代码块或者一个方法,从而实现锁的效果。

通过synchronized锁定的代码块或者方法同一时间只能由一个线程去执行,等这个线程执行完了释放锁了之后别的线程才能获取锁进入并且执行。

老王:那你说说synchronized的几种用法?

小陈:嘿嘿,这还不简单

synchronized的几种用法

(1)修饰在对象方法上:


public class SynDemo {
    int i = 0;
    int x = 0;
    public synchronized void  testSync() {
        i++;
        x++;
    }
}

放在实例方法上的时候,锁住的是这个SyncDemo的实例对象

(2)修饰在静态方法上:


public class SynDemo {
    static int value = 0;
    public synchronized static void testStaticSync() {
        value++;
    }
}

修饰在静态方法上的时候,的是这个类对应的类对象,也就是SyncDemo.class对象

(3)在方法内部的同步代码块:


public class SynDemo {
    int i = 0;
    int x = 0;
    Object lockObj = new Object();
    public void testInnerSync() {
        synchronized(lockObj) {
            i++;
            x++;
        }
    }
}

像这种方式,锁住其实就是lockObj这个对象。

小陈:老王,synchronized使用的三种方式我讲完了

synchronized注意事项

老王:既然你都知道使用的几种方式了,那么使用synchronized关键字需要注意的是什么?

小陈:其实synchronized是对一个对象上锁的,使用的时候需要注意在对同一个对象上锁才能达到互斥的目的。

我直接上代码来讲解一下吧:

(1)定义一个TestThread类,继承自Thread

(2)TestThread的内部持有一个SycDemo对象

(3)TestThread的run方法内部调用SyncDemo对象的testSync方法执行synchronized修饰的同步方法。


public class SynDemo {
    int i = 0;
    int x = 0;
    // 争抢对象SyncDemo的锁
    public synchronized void  testSync() {
        i++;
        x++;
    }
    static class TestThread extends Thread {
        SynDemo lock;
        TestThread(SynDemo lock) {
            this.lock = lock;
        }
        @Override
        public void run() {
            lock.testSync();
        }
    }
    public static void main(String[] args) {
        // 锁对象lock1
        SynDemo lock1 = new SynDemo();
        // 锁对象lock2
        SynDemo lock2 = new SynDemo();
        TestThread threadA = new TestThread(lock1);
        TestThread threadB = new TestThread(lock2);
        threadA.start();
        threadB.start();
    }
}

像这种方式,threadA和threadB是达不到互斥的目的的,因为threadA锁住的是lock1对象;然而thread锁住的是lock2对象。完全争抢的不是同一个锁。

image.png

老王:那如果要使得threadA和threadB达到同步的目的,应该怎么做?

小陈:需要threadA和threadB争抢同一把锁,争抢同一个同一个对象的锁才可以,也就是像下面那样,也就是threadA和threadB都使用同一对象锁ock1,这样才是正确的:


public static void main(String[] args) {
    // 只有一个锁对象lock1
    SynDemo lock1 = new SynDemo();
    // 两个线程对同一个对象锁进行争抢
    TestThread threadA = new TestThread(lock1);
    TestThread threadB = new TestThread(lock1);
    threadA.start();
    threadB.start();
}

image.png

小陈:对于synchronized修饰static的方法,synchronized锁的是这个类对象,由于类对象只有一个,所以不同线程同时通过类调用这个方法的时候就能互斥的效果

老王:嗯嗯,看来synchronized的使用方式、注意事项你都基本理解了;下面我们就来深入一点,开始探索synchronized的底层的实现原理了....

小陈:嘿嘿,终于可以进入原理级别去理解synchronized了......

老王:下一篇 《对象头、Mark Word、monitor、synchronized怎么关联起来?》 你别错过哦....

小陈:好的,老王,我们下一章见。

相关文章
|
7月前
|
安全 Java
深入学习Synchronized各种使用方法
深入学习Synchronized各种使用方法
75 4
|
7月前
|
存储 监控 安全
Synchronized 实现原理
Synchronized 实现原理
64 0
|
1天前
|
存储 Java C#
深入理解synchronized实现原理
本文深入讲解了Java中`synchronized`关键字的实现原理。`synchronized`确保同一时刻只有一个线程能进入临界区,并保证共享变量的内存可见性。它通过monitor机制实现,作用于方法时使用ACC_SYNCHRONIZED标志,作用于代码块时使用monitorenter和monitorexit指令。每个对象都有一个与之关联的monitor,线程需获取monitor锁才能执行同步代码。Monitor内部包含_EntryList、_Owner、_WaitSet等队列,管理线程的加锁、等待和唤醒过程。
深入理解synchronized实现原理
|
2月前
|
安全 Java
Synchronized是怎么实现的?
Synchronized是怎么实现的?
|
2月前
|
Java 编译器
synchronized 原理分析!
本文从字节码角度剖析`synchronized`关键字的工作原理,介绍其依赖的Java对象监视器锁机制,以及锁的获取、释放过程。文章还详细解释了偏向锁、轻量级锁等优化手段,并通过实例展示了同步方法和代码块的字节码实现。
36 0
|
4月前
|
Java
【多线程面试题十三】、说一说synchronized与Lock的区别
这篇文章讨论了Java中`synchronized`和`Lock`接口在多线程编程中的区别,包括它们在实现、使用、锁的释放、超时设置、锁状态查询以及锁的属性等方面的不同点。
架构系列——你可能不知道的那些synchronized使用细节
架构系列——你可能不知道的那些synchronized使用细节
|
7月前
|
Java
Synchronized实现原理(方法代码块)
Synchronized实现原理(方法代码块)
73 0
阅读完synchronized和ReentrantLock的源码后,我竟发现其完全相似
阅读完synchronized和ReentrantLock的源码后,我竟发现其完全相似
|
存储 Java
Synchronized 用法和底层原理
Synchronized 用法和底层原理
175 1