文档章节

synchronized 与 Lock 的区别

TonyStarkSir
 TonyStarkSir
发布于 2017/02/28 12:33
字数 838
阅读 40
收藏 0

同步的实现当然是采用锁了,java中使用锁的两个基本工具是 synchronized 和 Lock。

// 未同步的方法

public void test() {}

// 同步的方法

pubilc synchronized void test() {}

 

synchronized 也可以用在一个代码块上,看

 

public void test() {

     synchronized(obj) {

          System.out.println("===");

     }

}

synchronized 用在方法和代码块上有什么区别呢?

synchronized 用在方法名上,当某个线程调用此方法时,会获取该实例的对象锁,方法未结束之前,其他线程只能去等待。当这个方法执行完时,才会释放对象锁。其他线程才有机会去抢占这把锁,去执行该方法,但是发生这一切的基础应当是所有线程使用的同一个对象实例,才能实现互斥的现象。否则synchronized关键字将失去意义。

但是如果该方法为类方法,即其修饰符为static,那么synchronized 意味着某个调用此方法的线程当前会拥有该类的锁,只要该线程持续在当前方法内运行,其他线程依然无法获得方法的使用权!

synchronized 用在代码块的使用方式:synchronized(obj){//todo code here}

当线程运行到该代码块内,就会拥有obj对象的对象锁,如果多个线程共享同一个Object对象,那么此时就会形成互斥!特别的,当obj == this时,表示当前调用该方法的实例对象

public void test() {

     ...

     synchronized(this) {

          // todo your code

     }

     ...

}

此时,其效果等同于

public synchronized void test() {

     // todo your code

}

使用synchronized代码块,可以只对需要同步的代码进行同步,这样可以大大的提高效率。

小结:

使用synchronized 代码块相比方法有两点优势:

1、可以只对需要同步的使用

2、与wait()/notify()/nitifyAll()一起使用时,比较方便

除了wait()和notify()协作完成线程同步之外,使用Lock也可以完成同样的目的。

ReentrantLock 与synchronized有相同的并发性和内存语义,还包含了中断锁等候和定时锁等候,意味着线程A如果先获得了对象obj的锁,那么线程B可以在等待指定时间内依然无法获取锁,那么就会自动放弃该锁。

但是由于synchronized是在JVM层面实现的,因此系统可以监控锁的释放与否,而ReentrantLock使用代码实现的,系统无法自动释放锁,需要在代码中finally子句中显式释放锁lock.unlock();

public class Consumer implements Runnable {
 
     private Lock lock;
     public Consumer(Lock lock) {
            this. lock = lock;
     }
     @Override
     public void run() {
            // TODO Auto-generated method stub
            int count = 10;
            while( count > 0 ) {
                 try {
                      lock.lock();
                     count --;
                     System. out.print( "B");
                } finally {
                      lock.unlock(); //主动释放锁
                      try {
                           Thread. sleep(91L);
                     } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                           e.printStackTrace();
                     }
                }
           }
 
     }
 
}
 
public class Producer implements Runnable{
 
     private Lock lock;
     public Producer(Lock lock) {
            this. lock = lock;
     }
     @Override
     public void run() {
            // TODO Auto-generated method stub
            int count = 10;
            while (count > 0) {
                 try {
                      lock.lock();
                     count --;
                     System. out.print( "A");
                } finally {
                      lock.unlock();
                      try {
                           Thread. sleep(90L);
                     } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                           e.printStackTrace();
                     }
                }
           }
     }
}
 
//调用代码:
 
public class Test {
 
     public static void main(String[] args) {
           Lock lock = new ReentrantLock();
           
           Consumer consumer = new Consumer(lock);
           Producer producer = new Producer(lock);
           
            new Thread(consumer).start();
            new Thread( producer).start();
           
     }
}

使用建议:

在并发量比较小的情况下,使用synchronized是个不错的选择,但是在并发量比较高的情况下,其性能下降很严重,此时ReentrantLock是个不错的方案。

 

         ——摘自廖雪峰博客

 

© 著作权归作者所有

共有 人打赏支持
上一篇: JAVA常见的面试题
下一篇: MySQL的简单优化
TonyStarkSir
粉丝 2
博文 35
码字总数 36378
作品 0
杭州
后端工程师
私信 提问

暂无文章

中学生读《皮囊》有感相关体会4300字[图]

中学生读《皮囊》有感相关体会4300字[图]: 我们时常知道从哪里来,但很少知道自己要到哪里去,因为我们经常不认识自己,又怎能看见自己皮囊下最真实的面目?——题记 满怀欣喜去迎接五一,应...

原创小博客
11分钟前
2
0
java_集合

非并发集合 并发集合

grace_233
13分钟前
1
0
正则表达式匹配不包含

^((?!xxx).)*$

安小乐
24分钟前
1
0
python Windows tkinter应用开发3 列出目录的所有文件

在本章中,我们将编写程序来执行此操作。 1)选择文件夹。 2)在UI的标签部分打印该文件夹中的所有文件名(带文件扩展名)。 首先,修改selectFile函数以打开文件夹。主文件如下: from tki...

python测试开发人工智能安全
26分钟前
2
0
使用Laya引擎开发微信小游戏(上)

  使用一个简单的游戏开发示例,由浅入深,介绍了如何用Laya引擎开发微信小游戏。      img      作者:马晓东,腾讯前端高级工程师。      微信小游戏的推出也快一年时间了,...

SEOwhywhy
31分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部