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

  • 相关阅读:
    机房管理日记——2014/10/17
    ServletContext加入和访问
    打开系统设置
    阅读本书要瘦《面向对象的葵花宝典》札记-面向对象的基础
    Codeforces 327B-Hungry Sequence(素数筛)
    angularJS socket
    【Nginx】如何应对HTTP组态
    Android ActionBar详解(一):ActionBar概述及其创建
    Android高级图片滚动控件,编写3D版的图片轮播器
    Android自定义View的实现方法,带你一步步深入了解View(四)
  • 原文地址:https://www.cnblogs.com/yy3b2007com/p/11319038.html
Copyright © 2011-2022 走看看