JAVA中的锁——Synchronized

线程会出现的问题:同步 与 互斥

什么是同步? 什么是互斥?

Synchronized 可以作用于哪里?实现的原理?性能优化有什么?


 1.首先来说说什么是同步与互斥?

同步:线程间的通信(线程合作)

互斥:多线程并发时,某一时刻只能有一个线程访问共享资源

2.Synchronized同步处理可以作用于哪里(1)同步方法  (2)同步代码块

   (1)同步代码块锁的对象是  (this/ object及其子类 类对象 / 当前类.class)

Synchronized(锁的对象){
    //此处为代码在任意一个时刻只能有一个线程进去
}

 代码如下:

class sellTicket implements Runnable{
    private int ticket = 20000;
    @Override
    public void run() {
        while(ticket >0 ){
        synchronized (this){

                 try {
                     Thread.sleep(10);
                 } catch (InterruptedException e) {
                     e.printStackTrace();
                 }
                 System.out.println(Thread.currentThread().getName()+"还剩下"+ticket--+"票");
             }
         }
    }
}

public class SynchronizedTest {
    public static void main(String[] args) {
         Runnable runnable = new sellTicket();
         Thread thread1 = new Thread(runnable,"黄牛A");
         Thread thread2 = new Thread(runnable,"黄牛B");
         thread1.start();
         thread2.start();
    }
}

(2)同步方法:直接在方法声明上使用synchronized,此时表明同步方法在任意时刻只能有一个线程进入     (默认锁的是this)

         Synchronized修饰普通方法 ,  锁当前对象this

         Synchronized修饰类的静态方法 ,  锁当前类.class

代码如下:

class sellTicket implements Runnable{
    private int ticket = 20000;
    @Override
    public void run() {
        while(ticket >0 ) {
             sell();
        }
    }
    public synchronized void sell(){
        System.out.println(Thread.currentThread().getName()+"还剩下"+ticket--+"票");
    }

}

public class SynchronizedTest {
    public static void main(String[] args) {
         Runnable runnable = new sellTicket();
         Thread thread1 = new Thread(runnable,"黄牛A");
         Thread thread2 = new Thread(runnable,"黄牛B");
         thread1.start();
         thread2.start();
    }
}

3.Synchronized实现原理

   底层实现:在使用synchronized时必须保证锁定的对象必须为object以及其子类对象

                     synchronized使用的是JVM层级别的MonitorEnter与MonitorExit实现

                    这两个指令都必须获取对象的同步监视器Monitor

4.synchronized优化

     优化让每个线程通过同步代码块时速度提高,之前synchronized获取锁失败,将线程挂起——悲观锁

优化1:CAS

           什么是CAS?    Compare And Swap(无锁操作)是一种乐观锁

         CAS中有三个参数 (O,V,N)

        O:当前线程存储的变量值     V:内存中该变量的具体值   N:希望修改的变量值

       (1)当O == V时,此时表示还没有线程修改共享变量的值,此时可以成功将内存中的值改为N

       (2)当O != V时,此时表示内存中共享变量值已被其他线程修改,此时返回内存中的最新V,再次尝试修改变量

注意:CAS产生的问题

        1.ABA问题 :比如旧值A改为了B再改为了A,刚好在做CAS检查发现旧值并没有变化,实际已经改变   

             解决方法:添加一个版本号

        2.自旋会产生大量的处理器资源

                自旋:失败重试

              解决方式:JVM尝试自旋一段时间后,若在此时间内,线程成功获取到锁,再下次获取锁时,适当延长时间,反之,适当所短时间 

       3.公平性

         处于阻塞态线程可能会一直无法获取到锁 ,  LOCK锁可以实现公平性,Synchronized无法实现公平性

优化2:锁的升级  JDK1.6后默认偏向锁

           无锁 —>偏向锁  —>轻量级锁  —> 重量级锁

    偏向锁:进去同步方法或同步代码块始终是一个线程

    轻量级锁:不同时刻有不同线程尝试获取锁

    重量级锁:同一时刻请求同一把锁,有竞争 

注意:锁只有升级过程没有降级过程

其他优化: 锁的粗化与锁消除

  锁粗化:当出现多次连续的加锁与解锁过程,会将多次加锁减锁过程粗化为一次的加锁与解锁过程

  锁消除:当对象不属于共享资源时,对象内部的同步方法或同步代码块的锁会被自动解除

 

 

 

 

          

 

           

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Javasynchronized关键字用于实现线程同步,确保多个线程对共享资源的并发访问是安全的。它具有三个主要的作用:互斥访问、可见性和禁止指令重排。互斥访问指的是在同一时间只有一个线程可以执行被synchronized关键字包裹的代码块,从而保证了原子性。可见性指的是当一个线程修改了共享变量的值时,其他线程能够立即得知这个修改。禁止指令重排则是为了保证代码的执行顺序不会被优化或重排,从而确保程序的正确性。\[1\]\[2\] 在synchronized关键字的内部实现,它使用了的机制来实现线程的互斥访问。当一个线程进入synchronized代码块时,它会尝试获取,如果已经被其他线程持有,则该线程会被阻塞,直到被释放。当线程执行完synchronized代码块后,会释放,让其他线程有机会获取并执行相应的代码。这样就实现了线程的互斥访问。\[1\]\[2\] 总结来说,synchronized关键字是Java实现线程同步的一种基本手段,通过互斥访问、可见性和禁止指令重排来保证多线程对共享资源的安全访问。\[1\]\[2\] #### 引用[.reference_title] - *1* *3* [多线程——synchronized详解](https://blog.csdn.net/Pluto372/article/details/127304464)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}} ] [.reference_item] - *2* [synchronized实现线程同步的用法和实现原理](https://blog.csdn.net/u010013573/article/details/87219343)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值