打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
java之Synchronized(锁住对象和锁住代码)

1、问题

Synchronized我们一般都知道是锁,但是我们怎么区分是锁对象还是锁代码呢?


2、测试Demo

package leetcode.chenyu.test;

public class Synchronized {

 class Test {
public synchronized  void testFirst() {
print("testFirst");
}

public void testSecond() {
synchronized(this) {
print("testSecond");
}
}

public void testThird() {
synchronized(Test.class) {
print("testThird");
}
}

public  void print(String method) {
System.out.println(method + "start");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(method + "end");
}
}


class TestThread extends Thread {

public int mType = 0;
public Test mTest = null;

public TestThread(int type, Test test) {
this.mType = type;
this.mTest = test;
}

public void run() {
if (mTest == null) {
if (mType == 1) {
Test test = new Test();
test.testFirst();
}
else if (mType == 2) {
Test test = new Test();
test.testSecond(); 
} 
else if (mType == 3) {
Test test = new Test();
test.testThird(); 
}
} else {
if (mType == 1) {
mTest.testFirst();
}
else if (mType == 2) {
mTest.testSecond(); 
}
else if (mType == 3) {
mTest.testThird(); 
}
}
}
}


public static void main(String[] args) {
Synchronized syn = new Synchronized();
Test test = syn.new Test();
for (int i = 0; i < 5; ++i) {
syn.new TestThread(1, null).start();
}
}
}


3、运行结果和分析

1)、按照上面的运行结果

testFirststart
testFirststart
testFirststart
testFirststart
testFirststart
testFirstend
testFirstend
testFirstend
testFirstend
testFirstend

2)、把for循环里面的代码换如下

syn.new TestThread(2, null).start();

运行结果如下

testSecondstart
testSecondstart
testSecondstart
testSecondstart
testSecondstart
testSecondend
testSecondend
testSecondend
testSecondend
testSecondend

对于上面1)、2)、两种情况,synchronized(this)以及非static的synchronized方法,只能防止多个线程同时执行同一个对象的同步代码段,锁的是对象,也就是锁的本身this, 由于每个线程都新构建了一个新的对象,所以加了synchronized没有锁住。

3)、把for循环里面的代码换如下

syn.new TestThread(1, test).start();
syn.new TestThread(2, test).start();

运行结果都一样如下

testSecondstart
testSecondend
testSecondstart
testSecondend
testSecondstart
testSecondend
testSecondstart
testSecondend
testSecondstart
testSecondend

这里由于我们几个现场都共用一个对象,所以对象固定了,所以就锁住了,其它线程在没有释放锁的时候,进不来。

4)、把for循环里面的代码换如下

syn.new TestThread(3, null).start();
syn.new TestThread(3, test).start();

结果都如下

testThirdstart
testThirdend
testThirdstart
testThirdend
testThirdstart
testThirdend
testThirdstart
testThirdend
testThirdstart
testThirdend

synchronized(Test.class)实现了全局锁的效果,不管对象是不是一样的,都是同样的效果,就锁住代码了

我么一般用这个比较多。

4、总结

1、synchronized加在非静态方法前和synchronized(this)都是锁住了这个类的对象,如果多线程访问,对象不同,就锁不住,对象固定是一个,就可锁住。

2、synchronized(类名.class)和加在静态方法前,是锁住了代码块,不管多线程访问的时候对象是不是同一个,能缩小代码段的范围就尽量缩小,能在代码段上加同步就不要再整个方法上加同步,缩小锁的粒度。


4、总结

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Java线程同步:synchronized锁住的是代码还是对象
synchronized(){} 放在while里面和外面区别 可见性 同步代码块 并发 多线程
Java之Synchronized锁范围
java并发(十五)Java中的锁
【Java】基础33:用一个案例说明线程同步问题
java synchronized 用法 转自水木 java版 zms的贴子
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服