Java学习-锁-synchronized之对象锁和类锁

版权声明:欢迎转载,请注明作者和出处 https://blog.csdn.net/baichoufei90/article/details/83281014

Java学习-锁-synchronized之对象锁和类锁

0x01 摘要

synchronized是java中最常用的一种锁机制,本篇文章主要介绍他的两种用途:类锁和对象锁。

0x02 对象锁

synchronized作为对象锁时,用在非静态方法或非静态对象上,下面是示例:

	/**
     * 对象锁
     */
    public synchronized  void nonStaticMethodLock(){
        for(int i = 0 ; i< 5 ; i++){
            System.out.println(Thread.currentThread().getName()+" nonStaticMethodLock");
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 对象锁
     */
    public void objectLock(){
        synchronized(this){
            for(int i = 0 ; i< 5 ; i++){
                System.out.println(Thread.currentThread().getName()+" objectLock");
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

0x03 类锁

类锁修饰方法、代码块的效果和对象锁是一样的,因为类锁只是一个抽象出来的概念,只是为了区别静态方法的特点。因为静态方法是所有对象实例共用的,所以对应synchronized修饰的静态方法的锁也是唯一的,所以抽象出来个类锁。

下面是代码示例:

/**
     * 类锁
     */
    public void classLock(){
        synchronized(Test3.class){
            for(int i = 0 ; i< 5 ; i++){
                System.out.println(Thread.currentThread().getName()+" classLock");
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 类锁
     */
    public static synchronized  void staticMethodLock(){
        for(int i = 0 ; i< 5 ; i++){
            System.out.println(Thread.currentThread().getName()+" staticMethodLock");
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

0x04 代码示例

下面是完整的代码示例,可以自行调试观察结果,加深理解:

package demos.concurrent.thread.synchronizedTest.objectAndMethodLock;

/**
 * Created by chengc on 2018/10/22.
 */
public class Test3 {
    private Object nonStaticLockObj = new Object();
    private static Object staticLockObj = new Object();
    private static Object staticLockObj2 = new Object();

    /**
     * 类锁
     */
    public void classLock(){
        synchronized(Test3.class){
            for(int i = 0 ; i< 5 ; i++){
                System.out.println(Thread.currentThread().getName()+" classLock");
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 类锁
     */
    public static synchronized  void staticMethodLock(){
        for(int i = 0 ; i< 5 ; i++){
            System.out.println(Thread.currentThread().getName()+" staticMethodLock");
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    public void ordinaryMethod(){
        for(int i = 0 ; i< 5 ; i++){
            System.out.println(Thread.currentThread().getName()+" ordinaryMethod");
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 对象锁
     */
    public synchronized  void nonStaticMethodLock(){
        for(int i = 0 ; i< 5 ; i++){
            System.out.println(Thread.currentThread().getName()+" nonStaticMethodLock");
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 对象锁
     */
    public void thisObjectLock(){
        synchronized(this){
            for(int i = 0 ; i< 5 ; i++){
                System.out.println(Thread.currentThread().getName()+" thisObjectLock");
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 对象锁
     */
    public void nonStaticObjectLock(){
        synchronized(nonStaticLockObj){
            for(int i = 0 ; i< 5 ; i++){
                System.out.println(Thread.currentThread().getName()+" nonStaticLockObj");
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 对象锁
     */
    public void staticObjectLock(){
        synchronized(staticLockObj){
            for(int i = 0 ; i< 5 ; i++){
                System.out.println(Thread.currentThread().getName()+" staticLockObj");
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 对象锁
     */
    public void staticObjectLock2(){
        synchronized(staticLockObj2){
            for(int i = 0 ; i< 5 ; i++){
                System.out.println(Thread.currentThread().getName()+" staticLockObj2");
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void main(String[] args) {
        Test3 test1 = new Test3();
        new Thread(new Runnable() {
            @Override
            public void run() {
                test1.classLock();
            }
        },"Thread1").start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                test1.nonStaticMethodLock();
            }
        },"Thread2").start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                test1.ordinaryMethod();
            }
        },"Thread3").start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                test1.staticMethodLock();
            }
        },"Thread4").start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                test1.thisObjectLock();
            }
        },"Thread5").start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                test1.nonStaticObjectLock();
            }
        },"Thread6").start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                test1.staticObjectLock();
            }
        },"Thread7").start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                test1.staticObjectLock2();
            }
        },"Thread8").start();

    }
}

0x05 总结

通过以上代码调试,总结如下:

  1. 写在方法上的synchronized锁和写在代码块上用this修饰的对象锁同时只能有一个线程进入执行,但不影响其他方法执行
  2. 写在静态方法和代码块上用XXX.class修饰的为类锁,同时只能有一个线程进入执行,但不影响其他方法执行
  3. 用其他自己声明的对象作为对象锁修饰的方法或是代码块,互不影响
  4. 普通方法不受对象锁和类锁影响

猜你喜欢

转载自blog.csdn.net/baichoufei90/article/details/83281014
今日推荐