zoukankan      html  css  js  c++  java
  • Java同步的三种实现方式

    1.使用synchronized关键字修饰类或者代码块;

    2.使用Volatile关键字修饰变量;

    3.在类中加入重入锁

    举例子:多个线程在处理一个共享变量的时候,就会出现线程安全问题。(相当于多个窗口卖票的操作)

    非同步状态下:

    复制代码
    public static void main(String[] args){
            Increase increase = new Increase();
            int count = 10;
            while (count != 0){
                new Thread(() -> {
                    increase.increasementAndPrint();
                }).start();
                count --;
            }
        }
    
        static class Increase {
            private int i = 0;
    
            void increasementAndPrint() {
                System.out.print(i++ + "
    ");
            }
        }
    复制代码

    这种情况下可能会导致多个线程输出的i相同:

    0
    0
    1
    2
    3
    4
    5
    6
    7
    8

    使用同步:

    复制代码
    1.使用synchronized关键字
    //保证原子性和有序性
    static class Increase {
            private int i = 0;
    
            synchronized void increasementAndPrint() {
                System.out.println(i++);
            }
        }
    2.使用volatile
    //不保证原子性(一个被volatile声明的变量主要有可见性,有序性)
    static class Increase {
        private volatile int i = 0;
    
        void increasementAndPrint() {
            System.out.println(i++);
        }
    }

    volatile关键字不一定能够保证线程安全的问题,其实,在大多数情况下volatile还是可以保证变量的线程安全问题的。所以,在满足以下两个条件的情况下,volatile就能保证变量的线程安全问题:

    1. 运算结果并不依赖变量的当前值,或者能够确保只有单一的线程修改变量的值。
    3.使用重入锁
    //保证原子性和有序性
    static class Increase {
        private ReentrantLock reentrantLock = new ReentrantLock();
        private  int i = 0;
    
        void increasementAndPrint() {
            reentrantLock.lock();
            System.out.println(i++);
            reentrantLock.unlock();
        }
    }
  • 相关阅读:
    BUG记录
    .Net HTTP请求的发送方式与分析
    初始token
    VS2017开发安卓应用(Xamarin)
    路由模板和路由特性
    使用signalR创建聊天室。
    C# SessionHelper
    postgres递归查询所有子部门
    centos7备份postgres
    Centos7挂载硬盘
  • 原文地址:https://www.cnblogs.com/lgg20/p/11039543.html
Copyright © 2011-2022 走看看