synchronized 类锁&对象锁&私有锁

synchronized 类锁&对象锁

synchronized 类锁

概述

synchronized 类锁是作用于静态方法或者某一个具体的类上的锁。

语法

  • 作用于静态方法
synchronized public static void methodA() {
    // code
}
  • 作用于类
synchronized(Object.class) {
    // code 
}

synchronized 对象锁

概述

对象锁即作用于普通方法上(非静态)、类对象、this关键字上的锁

语法

  • 修饰普通方法
synchronized public void methodB() {
    // code
}
  • 修饰this关键字
synchronized(this) {
    // code 
}

synchronized 私有锁

概述

synchronized 私有锁即在类内部声明一个声明一个对象锁lock,在需要加锁的代码块中使用synchronized(obj)来加锁

语法

public class Test {
    // 套餐的奇妙
    private Object lock = new Object(); 
    private int i = 0;
    public void count(){
        // 加锁
        synchronized(lock){
            i++;
        }
    }
}

示例程序

对象锁、类锁、私有锁应用类

public class LockTestClass {

    // 用于类锁计数
    private static int i = 0;
    // 私有锁
    private Object object = new Object();

    /**
     * 无锁方法
     * @param threadID
     * @param thread
     */
    public void noSynMethod(long threadID, ObjThread thread) {
        System.out.println("nosyn: class obj is:\t" + thread + "\t threadId:\t" + threadID);
    }

    /**
     * 对象锁方法1
     * synchronized 修饰非静态方法
     */
    synchronized public void synOnMethod() {
        System.out.println("对象锁方法1:\t synchronized public void method:" + "\t\t当前时间毫秒数:\t" + System.currentTimeMillis() + "ms");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("对象锁方法1:\t synchronized public void method 结束");
    }

    /**
     * 对象锁方法2
     * synchronized 修饰 this 当前类对象
     */
    public void synInMethod() {
        synchronized(this) {
            System.out.println("对象锁方法2:\t synchronized(this):" + "\t\t当前时间毫秒数:\t" + System.currentTimeMillis() + "ms");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("对象锁方法2:\t synchronized(this)结束");
        }
    }

    /**
     * 私有锁
     * synchronized(obj) 修饰对象
     */
    public void synMethodWithObj() {
        synchronized(object) {
            System.out.println("私有锁:\t synchronized(obj):" + "\t\t当前时间毫秒数:\t" + System.currentTimeMillis() + "ms");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("私有锁:\t synchronized(obj)结束");
        }
    }

    /**
     * 类锁
     */
    synchronized public static void increament() {
        System.out.println("类锁: i = " + i + "\t\t当前时间毫秒数:\t" + System.currentTimeMillis() + "ms");
        i++;
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("类锁结束");
    }
}

线程类

public class ObjThread extends Thread {


    private LockTestClass lock;
    private int i = 0;

    public ObjThread(LockTestClass lock, int i) {
        this.lock = lock;
        this.i = i;
    }

    @Override
    public void run() {
//      // 无锁方法
//      lock.noSynMethod(this.getId(), this);
        // 对象锁方法1,synchronized 修饰非静态方法
        lock.synOnMethod();
        // 对象锁方法2, synchronized 修饰 this 当前类对象
        lock.synInMethod();
         私有锁方法,synchronized 修饰对象
//      lock.synMethodWithObj();
        // 类锁方法,synchronized修饰静态方法
//      LockTestClass.increament();


    }

}

注意:run()方法中根据不同的需要去测试

测试类

public class Test {

    public static void main(String[] args) {
        System.out.println("start time = " + System.currentTimeMillis()+"ms");
        LockTestClass test = new LockTestClass();
        for (int i = 0 ; i < 3 ; i ++) {
            Thread thread = new ObjThread(test, i);
            thread.start();
        } 
    }

}

测试结果

  • 对象锁&类锁

run()方法代码

@Override
    public void run() {
        // 无锁方法
//      lock.noSynMethod(this.getId(), this);
        // 对象锁方法1,synchronized 修饰非静态方法
        lock.synOnMethod();
        // 对象锁方法2, synchronized 修饰 this 当前类对象
//      lock.synInMethod();
        // 私有锁方法,synchronized 修饰对象
//      lock.synMethodWithObj();
        // 类锁方法,synchronized修饰静态方法
        LockTestClass.increament();
    }

终端输出:

start time = 1527579928236ms
对象锁方法1:  synchronized public void method:       当前时间毫秒数:    1527579928238ms
对象锁方法1:  synchronized public void method 结束
对象锁方法1:  synchronized public void method:       当前时间毫秒数:    1527579930243ms
类锁: i = 0       当前时间毫秒数:    1527579930243ms
对象锁方法1:  synchronized public void method 结束
类锁结束
对象锁方法1:  synchronized public void method:       当前时间毫秒数:    1527579932248ms
类锁: i = 1       当前时间毫秒数:    1527579932248ms
类锁结束
对象锁方法1:  synchronized public void method 结束
类锁: i = 2       当前时间毫秒数:    1527579934253ms
类锁结束

分析:当线程1启动时,优先执行了lock.synOnMethod();对象锁方法1,且休眠2秒后,线程2启动,并再次执行lock.synOnMethod();对象锁方法1,同时,类锁方法开始第一次执行(即线程1启动时)。说明类锁和对象锁之间不会产生竞争,互不影响。

  • 对象锁&私有锁

run()方法代码

@Override
    public void run() {
        // 无锁方法
//      lock.noSynMethod(this.getId(), this);
        // 对象锁方法1,synchronized 修饰非静态方法
        lock.synOnMethod();
        // 对象锁方法2, synchronized 修饰 this 当前类对象
//      lock.synInMethod();
        // 私有锁方法,synchronized 修饰对象
        lock.synMethodWithObj();
        // 类锁方法,synchronized修饰静态方法
//      LockTestClass.increament();
    }

终端输出:

start time = 1527581132501ms
对象锁方法1:  synchronized public void method:       当前时间毫秒数:    1527581132504ms
对象锁方法1:  synchronized public void method 结束
对象锁方法1:  synchronized public void method:       当前时间毫秒数:    1527581134507ms
私有锁:     synchronized(obj):     当前时间毫秒数:    1527581134507ms
对象锁方法1:  synchronized public void method 结束
私有锁:     synchronized(obj)结束
对象锁方法1:  synchronized public void method:       当前时间毫秒数:    1527581136513ms
私有锁:     synchronized(obj):     当前时间毫秒数:    1527581136513ms
对象锁方法1:  synchronized public void method 结束
私有锁:     synchronized(obj)结束
私有锁:     synchronized(obj):     当前时间毫秒数:    1527581138516ms
私有锁:     synchronized(obj)结束

分析:结果类似于对象锁&类锁。说明对象锁和私有锁之间也不会产生竞争、互不影响。

  • 对象锁&私有锁

run()方法代码

@Override
    public void run() {
        // 无锁方法
//      lock.noSynMethod(this.getId(), this);
        // 对象锁方法1,synchronized 修饰非静态方法
        lock.synOnMethod();
        // 对象锁方法2, synchronized 修饰 this 当前类对象
        lock.synInMethod();
        // 私有锁方法,synchronized 修饰对象
//      lock.synMethodWithObj();
        // 类锁方法,synchronized修饰静态方法
//      LockTestClass.increament();
    }

终端输出:

start time = 1527581386649ms
对象锁方法1:  synchronized public void method:       当前时间毫秒数:    1527581386650ms
对象锁方法1:  synchronized public void method 结束
对象锁方法1:  synchronized public void method:       当前时间毫秒数:    1527581388655ms
对象锁方法1:  synchronized public void method 结束
对象锁方法2:  synchronized(this):        当前时间毫秒数:    1527581390657ms
对象锁方法2:  synchronized(this)结束
对象锁方法1:  synchronized public void method:       当前时间毫秒数:    1527581392659ms
对象锁方法1:  synchronized public void method 结束
对象锁方法2:  synchronized(this):        当前时间毫秒数:    1527581394663ms
对象锁方法2:  synchronized(this)结束
对象锁方法2:  synchronized(this):        当前时间毫秒数:    1527581396664ms
对象锁方法2:  synchronized(this)结束

分析:两者结果串行输出,注意再次执行时,是lock.synOnMethod();先运行还是lock.synInMethod();先运行取决于两者谁先获取锁。

synchronized 类锁&对象锁&私有锁 比较结论

  • 类锁&对象锁:多线程运行过程中,类锁与对象锁不产生锁竞争、各自运行、互不影响
  • 对象锁&私有锁:多线程运行过程中,对象锁&私有锁不产生锁竞争、各自运行、互不影响
  • 对象锁&对象锁:synchronized(this)synchronized public void method()都是在当前对象上加锁,且形成了锁竞争关系,同一时刻只能有一个方法能执行。

参考链接:
http://ifeve.com/java-locks/
https://blog.csdn.net/luoweifu/article/details/46613015这里写链接内容
https://blog.csdn.net/qyp199312/article/details/78438273
https://www.cnblogs.com/owenma/p/8609348.html

源代码链接:
https://github.com/myNameIssls/javase-study/tree/master/javase-multithreading/src/main/java/cn/tyrone/javase/multithreading/synchronizeddemo/locktype

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值