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方式实现。

  • 相关阅读:
    Hash
    字符串hash
    NOIp 2014解方程
    NOIp2014 寻找道路
    NOIp2013火柴排队
    用scanf("%d",)读入long long类型
    lis问题
    西江月·证明
    计算系数
    积木大赛&PLA-Postering
  • 原文地址:https://www.cnblogs.com/yy3b2007com/p/11319038.html
Copyright © 2011-2022 走看看