zoukankan      html  css  js  c++  java
  • 使用无锁完成多线程模拟售票, 理解无锁是啥?

    实现的模拟多线程实现售票是每个学习多线程的初学者必须要学会掌握的知识点, 既然掌握的它, 我们自然要举一反三

    So~, 无锁版出现了

    What无锁?

    假如两个线程同时修改一个变量的场景下

    我们需要三个值, 预期值(线程副本变量中的值), 主存值(从主存变量中的值), 新值(我们要设置的值)

    如果 预期值 不等于 主存值 则忽略 新值 写入  =========> 这句话是一个原子操作, 是不可分割的(就是内存屏障), 在执行这个过程中, 是不会失去时间片的

    如果 预期值 等于 主存值 则  新值 写入  =========> 这句话是一个原子操作, 是不可分割的(就是内存屏障), 在执行这个过程中, 是不会失去时间片的

    直接上代码就能理解了, 这是多线程模拟售票的案例, 里面有无锁和加锁的案例

    package com.zhazha.juc;
    
    import org.junit.Test;
    import java.util.concurrent.CountDownLatch;
    import java.util.concurrent.atomic.AtomicInteger;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    /**
     * @author zhazha
     * @version 1.0.0
     * @date 2019/10/19 9:39
     * @msg
     **/
    public class TestTicketAtomicLock {
    
        @Test
        public void test01() throws Exception {
            CountDownLatch latch = new CountDownLatch(3);
            TicketAtomic ticket = new TicketAtomic(latch);
            for (int i = 0; i < 3; i++) {
                new Thread(ticket).start();
            }
            latch.await();
        }
    
        @Test
        public void test() throws Exception {
            CountDownLatch latch = new CountDownLatch(3);
            TicketNonAtomic ticket = new TicketNonAtomic(latch);
            for (int i = 0; i < 3; i++) {
                new Thread(ticket).start();
            }
            latch.await();
        }
    
    }
    
    
    class TicketAtomic implements Runnable {
    
        private AtomicInteger ticket = new AtomicInteger(100);
        private CountDownLatch latch;
    
        public TicketAtomic(CountDownLatch latch) {
            this.latch = latch;
        }
    
        @Override
        public void run() {
            while (true) {
                try {
                    int temp = ticket.get();
                    if (temp > 0) {
                        // TimeUnit.MILLISECONDS.sleep(100);
                        if (ticket.compareAndSet(temp, ticket.get() - 1)) {
                            System.out.println(Thread.currentThread().getName() + " 	成功售票, 余票为: " + ticket.get());
                        }
                    }
                    else {
                        break;
                    }
                }
                catch (Exception e) {
                    e.printStackTrace();
                }
            }
            latch.countDown();
        }
    }
    
    
    class TicketNonAtomic implements Runnable {
    
        private Integer ticket = 100;
        private Lock lock = new ReentrantLock();
        private CountDownLatch latch;
    
        public TicketNonAtomic(CountDownLatch latch) {
            this.latch = latch;
        }
    
        @Override
        public void run() {
            while (true) {
                lock.lock();
                try {
                    if (ticket > 0) {
                        // TimeUnit.MILLISECONDS.sleep(100);
                        System.out.println(Thread.currentThread().getName() + " 	成功售票, 余票为: " + --ticket);
                    }
                    else {
                        break;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }
            latch.countDown();
        }
    }
    

    上面无锁代码中, 最重要的是这句话

    if (ticket.compareAndSet(temp, ticket.get() - 1)) {

    内部代码

     再进去就是用c++实现的无锁

     这步是原子性操作的, 整个过程

    如果 预期值 不等于 主存值 则忽略 新值 写入 等于 主存值 则 写入

  • 相关阅读:
    CentOS-Docker安装RabbitMQ(单点)
    CentOS-关闭防火墙和禁用安全策略
    CentOS-Docker搭建VeryNginx
    CentOS7-磁盘扩容(LVM-非空目录拓展卷空间大小)
    (六十二)Activity的启动模式(转载自http://blog.csdn.net/android_tutor/article/details/6310015)
    (一)关于SWT程序的基本架构,如何使用控件以及使用Image,Font,Color等图形资源内容
    (六十一)eclipse老是卡顿的问题解决办法
    (六十一)Activity启动模式 及 Intent Flags 与 栈 的关联分析(转载自:http://blog.csdn.net/vipzjyno1/article/details/25463457)
    (六十)工具方法---隐藏软键盘
    iOS 语音朗读
  • 原文地址:https://www.cnblogs.com/bangiao/p/11703277.html
Copyright © 2011-2022 走看看