Synchroized锁的是什么

Synchroized锁的是什么

闲来无事,写篇文章,讲讲synchronized锁的到底是什么。

1.Synchronized怎么用?

​ 一般Synchronized有如下三种用法:

/**
* 下边两种是一样的情况
*/
synchronized (this) {
  ......
}

//--------------------------------------------

Object object=new Object();
synchronized (object) {
  ......
}
public synchronized void demoSync() {
  ......
}
public static synchronized void demoSync2() {
  ......
}

他可以在()放一个实例对象(this其实就是本对象),还可以放在静态方法上锁柱一个静态方法,还可以放在一个普通方法上锁住一个普通方法。

2.Synchronized锁的是什么?

解析完了上边的三种用法,那么这三种用法有什么区别呢,都锁的是什么?

其实synchronized最终只会锁柱两个东西:

  • 对象实例
  • 一个类

​ 如果锁住静态方法也是锁的类,如果给一个普通方法上锁那么锁住的是当前的实例对象,上述代码中的第一种用法就显而易见了,如果()中放了this就是锁住的是当前的对象,如果放了其他对象那么锁的就是其他对象。我们通过jvm的基础知识可以知道一个类在jvm中如果不用多余的类加载器加载class一定是只存在一份的,但是实例对象可以存在多份。

​ 我们来写写代码分析下这几种情况吧,先写一个类,来实现synchronized的各种用法,

class Demo1 {

    private Object object;

    public Demo1(Object object) {
        this.object = object;
    }

    public synchronized void demoSync() {
        while (true) {
            //打印当前线程的信息
            System.out.println("demoSync---------" + Thread.currentThread());
        }
    }

    public static synchronized void demoSync2() {
        while (true) {
            //打印当前线程的信息
            System.out.println("demoSync2------" + Thread.currentThread());
        }
    }


    public void demoSync3() {
        synchronized (this) {
            while (true) {
                //打印当前线程的信息
                System.out.println("demoSync3---------" + Thread.currentThread());
            }
        }
    }

    public void demoSync4() {
        synchronized (object) {
            while (true) {
                //打印当前线程的信息
                System.out.println("demoSync4---------" + Thread.currentThread());
            }
        }
    }

}

第一种情况:

  public static void main(String[] args) {

        //三个线程 调用 demo类的demoSync方法
        for (int i = 0; i < 3; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    Demo1 demo1 = new Demo1();
                    demo1.demoSync();
 
                }
            }).start();
        } 

    }

执行结果如下:

在这里插入图片描述

我们可以看到我们创建的三个线程都进去执行了,并没有达到同步的目的,这是因为每个线程都会创建一个Demo1的实例对象,然后调用每个实例对象的demoSync方法,由于锁的是本对象所以就出现了未能同步的效果。

我们进行一下反证法再去证明一下这个问题,我们对代码做如下修改:

/**
 * 创建一个线程类,通过该类的构造方法将一个固定的对象传入,然后调用该对象的
 * demoSync方法。
 */
class TestThread extends Thread {

    private Demo1 demo1;

    public TestThread(Demo1 demo1) {
        this.demo1 = demo1;
    }

    @Override
    public void run() {
        demo1.demoSync();
    }

}

main方法代码如下:

 public static void main(String[] args) {
	Demo1 demo1 = new Demo1();
	new TestThread(demo1).start();
 }	

我们得到的结果如图:

在这里插入图片描述

在图中并没其他线程进入,所以我们的修改使得代码同步了,因为此时我们保证了三个线程都是调用的同一个对象的demoSync方法。通过上边的两个代码实例我们可以看出如果synchronized修饰了一个普通方法,那么它锁住的就是本对象。

接下来我们分析下synchronized修饰静态方法的情况,我们的代码如下:

 public static void main(String[] args) { 
        for (int i = 0; i < 3; i++) {
             new Thread(new Runnable() {
                 @Override
                 public void run() {
                     Demo1 demo1 = new Demo1();
                     demo1.demoSync2();
                 }
             }).start();
         }
 }

运行结果为

在这里插入图片描述

我们发现了只有0号线程进入了其中并没有之前的三个线程都会进入的情况,这说明,此时锁住的肯定不是当前对象了,那么它一定是锁的类,因为他只会锁两种。由此我们分析完了这种修饰静态方法的情况。它其实就相当于synchronized(Object.class)。

总结:另外的最为普通的两种方式synchronized(this)和synchronized(object)就不做多余的测试了,其实和上边的两种情况是类似的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值