synchronized和volatile

synchronized

三种应用方式

  1. 实例方法:锁是当前的实例对象

    //        实例方法    多个线程访问对象的同一个方法
     
    public class S1 implements Runnable{
    
        static int a = 0;   //共享
    
        
        synchronized void add(){                                                
            a++;
        }
        @Override
        public void run() {
            for (int i = 0; i <2000 ; i++) {
                add();
            }
        }
    
        public static void main(String[] args) throws InterruptedException {
    
            S1 s1 = new S1();
            Thread t1 = new Thread(s1);     
            Thread t2 = new Thread(s1);
                                                            
            t1.start();
            t2.start();
    
            t1.join();
            t2.join();
    
            System.out.println(a);
        }
    }
    //输出:4000
    //一个对象只有一把锁,多个线程同时对一个的对象的一个方法进行操作,只有一个线程能抢到锁,其他未抢到锁的线程不能访问该对象的其他synchronized实例方法 ,需要等待对象被释放后才能获取锁,对象没有被释放前,其他可以线程访问 非synchronized修饰的方法
    
    
  2. 静态方法

    //         静态方法
    
    public class S2 implements Runnable{
    
        static int a = 0;   //共享
    
    
        static synchronized void add(){
            a++;
        }
        @Override
        public void run() {
            for (int i = 0; i <2000 ; i++) {
                add();
            }
        }
    
        public static void main(String[] args) throws InterruptedException {
    
    
            Thread t1 = new Thread(new S2());
            Thread t2 = new Thread(new S2());
    
            t1.start();
            t2.start();
    
            t1.join();
            t2.join();
    
            System.out.println(a);
        }
    }
    
    //输出:4000
    //两个线程实例化不同的对象,但是访问的方法是static修饰的,两个线程发生了互斥,因为static方法依附于 类 ,不依赖于对象,当synchronized修饰static method时,锁是 class对象(唯一)
    
  3. 代码块

             同步代码块
     */
    public class S3 implements Runnable{
        static S3 syn = new S3();   //静态对象
        static int a = 0;
    
        @Override
        public void run(){
            //。。。
            //。。。
    //        synchronized(syn){			//给定的实例对象
    //            for (int i = 0; i <2000 ; i++) {
    //                a++;
    //            }
    //        }
            
    //        synchronized(this){			//this对象(当前实例)
    //            for (int i = 0; i <2000 ; i++) {
    //                a++;
    //            }
    //        }
            synchronized(S3.class){			//calss对象
                for (int i = 0; i <2000 ; i++) {
                    a++;
                }
            }
        }
    
        public static void main(String[] args) throws InterruptedException {
    
            Thread t1 = new Thread(syn);
            Thread t2 = new Thread(syn);
    
            t1.start();
            t2.start();
    
            t1.join();
            t2.join();
            System.out.println(a);
        }
    }
    
    

volatile

定义:是Java虚拟机提供的轻量级同步机制。

特性

  1. 保证可见性

    • 线程A和线程B共享同一变量,线程A对共享变量值修改后,线程B会得到最先的修改结果。
  2. 不保证原子性【可以使用 juc 下的atomic来保证原子性】

    • 会因为线程调度器而被中断操作
  3. 禁止指令重排【通过 内存屏障 保证指令的有序性】

    • 程序执行的最终结果与其顺序化执行的结果相同
    • DCL中会造成线程不安全
    指令重排:
    	JVM允许指令执行的顺序与   代码逻辑书写的顺序可以不一致
    	
    意义:
    	指令更加符合CPU的特性,提高执行效率
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值