synchronized锁
Posted xieyanke
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了synchronized锁相关的知识,希望对你有一定的参考价值。
基础知识:
每一个对象都有一个监听器(monitor)且只有一个
synchronized锁可分为对象锁和静态锁, 顾名思义对象锁就是给实例对象进行加锁, 静态锁则是给类进行加锁
举个例子:好比上厕所, 第一个人进厕所后把厕所门锁住,后面的人就只能排队进等待, 直到前面一个人把厕所门打开
synchronized常见方式如下:
1 对象方法加锁(对象锁)
public synchronized void test(){ //doSomething。。。。。 }
2 静态方法加锁(静态锁)
public synchronized static void test(){ //doSomething。。。。。 }
3 对象加锁(对象锁)
Object object = new Object(); public void test(){ synchronized (object){ //doSomeing。。。。 } }
4 方法中给类加锁(静态锁)
public void test(){ synchronized (SocketServerTest.class){ //doSomeing。。。。 }
}
思考:
对象锁锁住对象, 若其他方法块需要获取当前对象锁则必须排队等待释放; 静态锁(也称为类锁)则是在使用类加锁或静态方法加锁时需要排队
那么问题来了若类锁和对象锁共存是一种什么样的情况呢, 我们给静态方法和普通方法都加上锁
对于以下代码我们可以预测可能会有两种情况
1对象锁和类锁为互斥, 需要排队 预测结果 test1 test2 tStatic1 tStatic2
2对象锁和类锁无关联,各自作用域不同 预测结果 tStatic1 tStatic2 test1 test2
public static void main(String[] args) throws InterruptedException {
Test test = new Test();
Thread t1 = new Thread(()->test.test1());
Thread t2 = new Thread(()->test.test2());
Thread tStatic1 = new Thread(()->Test.testStatic1());
Thread tStatic2 = new Thread(()->Test.testStatic2());
t1.start();
//保证t2在t1之后获取锁
Thread.sleep(300);
t2.start();
//保证tStatic1在t2之后获取锁
Thread.sleep(300);
tStatic1.start();
//保证tStatic2在tStatic1之后获取锁
Thread.sleep(300);
tStatic2.start();
}
public static class Test{
public synchronized void test1() {
//休眠5秒
try {
Thread.sleep(5*1000);
}catch (Exception e){
e.printStackTrace();
}
System.out.println("test1");
}
public void test2() {
synchronized (this){
System.out.println("test2");
}
}
public synchronized static void testStatic1(){
//休眠3秒
try {
Thread.sleep(3*1000);
}catch (Exception e){
e.printStackTrace();
}
System.out.println("testStatic1");
}
public static void testStatic2(){
synchronized (Test.class){
System.out.println("testStatic2");
}
}
}
打印结果:
testStatic1
testStatic2
test1
test2
从以上结果可以看出,对象锁和类锁完全互不影响
那么回到上面上厕所的例子, 那么对象锁和类锁就意味着互不影响的两个厕所门,做个简单命名对象厕所, 类厕所, 选择上对象厕所的人需要等待前面对象厕所的人出来, 同理等待类厕所的人也一样要等待前面的人出来
通常情况下挺合情合理, 但是如果厕所里面有洗手台,有蹲坑, 那么对于只想洗手的人而言显然就不合理了, 洗手只要十几秒而且人很多, 真正上厕所的人少而且时间特别长,显然synchronized很有局限性无法解决这个问题, 就需要使用到读写锁
以上是关于synchronized锁的主要内容,如果未能解决你的问题,请参考以下文章