• Java-JUC(十三):现在有两个线程同时操作一个整数I,做自增操作,如何实现I的线程安全性?


    问题分析:正如i在多线程中如果想实现i的多线程操作,必须i要使用volitle来保证其内存可见性,但是i++自增操作不具备原子性操作,因此需要对i++这段代码确保其原子性操作即可。

    方案1:

    使用ReetranLock实现i++的原子性操作。

    private static volatile int i=0;
        public static void main(String[] args) throws InterruptedException {
            CountDownLatch countDownLatch=new CountDownLatch(2);
            Lock lock=new ReentrantLock();
            Thread thread1 = new Thread(new Runnable() {
                @Override
                public void run() {
                    try{
                        lock.lock();
                        i++;
                    }finally{
                        lock.unlock();
                        countDownLatch.countDown();
                    }
                }
            },"Thread-1");
            Thread thread2 = new Thread(new Runnable() {
                @Override
                public void run() {
                    try{
                        lock.lock();
                        i++;
                    }finally{
                        lock.unlock();
                        countDownLatch.countDown();
                    }
                }
            },"Thread-2");
            thread1.start();
            thread2.start();
            countDownLatch.await();
    
            System.out.println(i);
        }

    方案2:

    使用Semaphore实现i++的原子性操作。

    private static volatile int i = 0;
    
        public static void main(String[] args) throws InterruptedException {
            CountDownLatch countDownLatch = new CountDownLatch(2);
            Semaphore semaphore = new Semaphore(1);
            Thread thread1 = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        semaphore.acquire();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    i++;
                    semaphore.release();
                    countDownLatch.countDown();
                }
            }, "Thread-1");
            Thread thread2 = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        semaphore.acquire();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    i++;
                    semaphore.release();
                    countDownLatch.countDown();
                }
            }, "Thread-2");
            thread1.start();
            thread2.start();
            countDownLatch.await();
    
            System.out.println(i);
        }

     当然也可以选择sychronized方式实现。

  • 相关阅读:
    git 相关
    3D渲染相关基本概念
    c#调用GDAL判断图片文件是否损坏
    8.26 轩然大波
    宽容与未来
    vue学习:打开/刷新一个页面时,触发一个后端请求
    linux histroy显示时间
    从数的角度理解视角转换
    对非法网站的一次提权
    简单的BC站点getshell
  • 原文地址:https://www.cnblogs.com/yy3b2007com/p/11319038.html
Copyright © 2020-2023  润新知