zoukankan      html  css  js  c++  java
  • 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方式实现。

  • 相关阅读:
    超简单tensorflow入门优化程序&&tensorboard可视化
    tf.random_normal()函数
    tensorflow中创建多个计算图(Graph)
    tensorflow中有向图(计算图、Graph)、上下文环境(Session)和执行流程
    配置错误 在唯一密钥属性“fileExtension”设置为“.log”时,无法添加类型为“mimeMap”的重复集合项
    取奇偶数
    DNS添加/修改/查询/删除A记录
    IE自动化
    Get-ChildItem参数之 -Exclude,Filter,Recurse应用
    自动下载
  • 原文地址:https://www.cnblogs.com/yy3b2007com/p/11319038.html
Copyright © 2011-2022 走看看