线程的synchronized、volatile及原子操作

public class ThreadDemo7{
    //structs2线程不安全  共享变量
    //n++ 复合操作  对于volatile修饰的变量不安全
    //原子操作
    int  value;

    //让方法变成一个同步的方法
    public synchronized int nextValue(){
        return value ++;
    }
    public static void main(String[] args){
        ThreadDemo7 t1 = new ThreadDemo7();
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true){
                    System.out.println(t1.nextValue() + " " + Thread.currentThread().getName());
                }
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true){
                    System.out.println(t1.nextValue() + " " + Thread.currentThread().getName());
                }
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true){
                    System.out.println(t1.nextValue() + " " + Thread.currentThread().getName());
                }
            }
        }).start();
    }
}
public class ThreadDemo7_1 {
    private static volatile int num;

    //使用countDownLatch来等待使线程执行完
    public static CountDownLatch countDownLatch = new CountDownLatch(30);

    //由于n++是复合操作,所以并不能保证线程安全
    //public synchronized  int NextValue(){
    public int NextValue(){
        return num ++;
    }
    public static void main(String[] args){
        ThreadDemo7_1 t1 = new ThreadDemo7_1();

        for(int i=0;i<30;i++){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    for(int j=0;j<10000;j++){
                        t1.NextValue();
                    }
                    countDownLatch.countDown();
                }
            }).start();
        }
        try{
            countDownLatch.await();
        }catch (InterruptedException e){
            e.getMessage();
        }

        System.out.println(num);
    }
}
public class ThreadDemo7_2 {
    private static AtomicInteger num = new AtomicInteger();

    //使用countDownLatch来等待使线程执行完
    public static CountDownLatch countDownLatch = new CountDownLatch(30);

    public static void main(String[] args){
        ThreadDemo7_1 t1 = new ThreadDemo7_1();

        for(int i=0;i<30;i++){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    for(int j=0;j<10000;j++){
                        num.incrementAndGet(); //原子性的num++,通过cas方式
                    }
                    countDownLatch.countDown();
                }
            }).start();
        }
        try{
            countDownLatch.await();
        }catch (InterruptedException e){
            e.getMessage();
        }

        System.out.println(num);
    }

概念解析

并发机制依赖于JVM的实现和CPU的指令
1. volatile一般在多线程中使用,保证共享变量的可见性,解决并发带来的问题
可见性意思就是一个线程修改另外一个线程可以看到修改后的值,通过排它锁单独获得这个变量
volatile执行成本低,因为不会引起线程上下文的切换和调度
synchronized是重量级锁
2. volatile深层理解
有volatile变量修饰的共享变量进行读写操作的时候会多出第二行汇编代码
lock前缀的指令在多核处理器下会引发两件事情:
1)lock前缀指令会引起处理器缓存回写到内存
2)这个写回内存的操作会使在其他CPU里缓存了该内存地址的数据无效
3. synchronized实现同步的基础:java中的每一个对象都可以作为锁
具体表现如下:
1)对于普通同步方法,锁是当前实例对象
2)对于静态同步方法,锁是当前类的class对象
3)对于同步方法块,锁是synchronized括号里配置的对象
当一个线程视图访问同步代码块时,它首先必须得到锁,退出或抛出异常时必须释放锁
Synchronized在JVM里的实现原理:JVM基于进入和退出Monitor对象来实现方法同步和代码块同步
2. 无锁,偏向锁,轻量级锁,重量级锁

猜你喜欢

转载自www.cnblogs.com/mutong1228/p/10491851.html
今日推荐