笔记_并发编程实践_十五

原子变量与非阻塞同步机制
1.锁的劣势:
(1)需然jvm对非竞争的锁的获取和释放优化至非常高效,但是但该锁频繁地繁盛竞争时。调度与真正用于工作的开小间的比值会很可观。
(2)优先级倒置问题,当低优先级的线程持有锁,并发生任何延迟,高优先级的线程都不会被执行。
2.硬件对并发的支持
(1底层处理器具有原子化的“测试并设置”,“获取并增加”以及“交换”指令,现代的处理器具有一些原子化的读-改-写操作,如“比较并交换”,“加载链接/存储条件”
但是在jdk5以前,这些还不能直接为java类所用
(2)比较并交换:
<1>比较并交换式一项乐观锁技术,意思是:“我认为v的值应该是a,如果是则赋值b,如果不是,则返回v的值”
<2>cas比锁更高效,但是更复杂
<3>原子变量AtomicXX都提供compareAndSet方法(域更新器的comapareAndSet同样可以实现)

3.比较锁和原子变量
(1)在中低竞争的情况下原子变量的性能比较好,在高强度竞争下,锁能够很好地避免竞争(由于compareAndSet实现的原子变量,类似于乐观锁,会在设置失败后重新设置,在高强度竞争下会导致更多的竞争)
4.非阻塞算法
(1)构建非阻塞算法的窍门是:缩小原子化的非为到唯一的变量(该变量使用原子变量AutomicXX,利用其CompareAndSet方法“投机地”更新值这一最基本的模式)
(2)非阻塞链表,队列,原子化的域更新器的实现
(3)原子化的域更新器:
<1>更新器类没有构造函数,通过newUpdater的工厂方法,生命类的和域的名称
<2>提供较弱的原子性,只能保证通过与更新器去更新域时原子操作,但是通过其他途径可以修改该属性
(4)ABA问题:
(1)这是compareAndSet无用引起的反常现象,主要存在于不能被垃圾回收的环境中,也就是当compare一部的时候,比较到当前值是否为A时,可能A已经转换为B在转换为A,在这一情况下肯能使得compareAndSeet同样成功。
(2)简单的解决方法,更新一对值而不是一个值,即引用版本号,那么即使a改为b后再改为a,版本号也是不同的。
(3)AtomicStampedReference和AtomicMarkableReference提供了一对变量原子化的条件更新。
5.一些练习:(注意,若向使用类似的容器应该使用jdk提供的,只是练习compareAndSet)

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package TestConcurrent;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.atomic.AtomicReference;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * 尝试使用原子变量的compareAndSet实现同步的堆栈 注意一点CAS对比锁的使用,在中低级的竞争环境下可以提供更高的效率
 *
 */
public class TestConcurrentStack {

//使用AtomicReference、构建Node类型的原子变量,代表当前栈顶
    AtomicReference<Node> top = new AtomicReference<Node>();

    public TestConcurrentStack() {
        top.set(new Node());
    }

    public void push(Object value) {
        //获得当前top值以使用cas
        Node oldHead;
        Node newHead;
        do {
            oldHead = top.get();
            newHead = new Node(oldHead, value);
        } while (!top.compareAndSet(oldHead, newHead));
    }

    public Object pop() {
        Node oldHead;
        Node newHead = null;
        Boolean result = false;
        do {
            oldHead = top.get();
            if (oldHead == null || oldHead.next == null) {
                try {
                    Thread.sleep(Double.valueOf(Math.random() * 1000).longValue());
                    continue;
                } catch (InterruptedException ex) {
                    Logger.getLogger(TestConcurrentStack.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
            newHead = oldHead.next;
            result = top.compareAndSet(oldHead, newHead);
        } while (!result);
        return oldHead.value;
    }

    public static void main(String args[]) {
        TestConcurrentStack stack = new TestConcurrentStack();
        CyclicBarrier barrier = new CyclicBarrier(1000);//保证线程同一时间起跑
        List<Thread> list = new ArrayList();
        for (int i = 0; i < 510; i++) {
            Thread t = new Thread(new pusher(stack, barrier));
            list.add(t);
            t.start();
        }
        for (int i = 0; i < 490; i++) {
            Thread t = new Thread(new poper(stack, barrier));
            list.add(t);
            t.start();
        }
        for (Thread t : list) {
            try {
                t.join();
            } catch (InterruptedException ex) {
                Logger.getLogger(TestConcurrentStack.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        System.out.println("-------以下将打印出当前堆栈中的各个对象-----");
        Node curNode = stack.top.get();
        int i = 0;
        while (curNode != null) {
            System.out.println("【"
                    + curNode.value + "】");
            curNode = curNode.next;
            i++;
        }
        System.out.println("------------------栈中还有【" + i + "】个数据----------------------");
    }

    public static class pusher implements Runnable {

        TestConcurrentStack stack;
        CyclicBarrier barrier;

        public pusher(TestConcurrentStack stack, CyclicBarrier barrier) {
            this.stack = stack;
            this.barrier = barrier;
        }

        @Override
        public void run() {
            try {
                barrier.await();
                Thread.sleep(1000);
                this.stack.push(Thread.currentThread().getName() + "插入数据");
            } catch (InterruptedException ex) {
                Logger.getLogger(TestConcurrentStack.class.getName()).log(Level.SEVERE, null, ex);
            } catch (BrokenBarrierException ex) {
                Logger.getLogger(TestConcurrentStack.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

    }

    public static class poper implements Runnable {

        TestConcurrentStack stack;
        CyclicBarrier barrier;

        public poper(TestConcurrentStack stack, CyclicBarrier barrier) {
            this.stack = stack;
            this.barrier = barrier;
        }

        @Override
        public void run() {
            try {
                barrier.await();
                Thread.sleep(1000);
                Object value = this.stack.pop();
                if (value != null) {
                    System.out.println(Thread.currentThread().getName() + "删除了数据【"
                            + value + "】");
                } else {
//                    System.out.println(Thread.currentThread().getName() + "当前栈顶为空  【               】 ");
                }
            } catch (InterruptedException ex) {
                Logger.getLogger(TestConcurrentStack.class.getName()).log(Level.SEVERE, null, ex);
            } catch (BrokenBarrierException ex) {
                Logger.getLogger(TestConcurrentStack.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

    }

    /**
     * 代表节点
     */
    public static class Node {

        public Node next;
        public Object value;

        public Node() {

        }

        public Node(Node next, Object value) {
            this.next = next;
            this.value = value;
        }

        @Override
        public boolean equals(Object obj) {
            if (obj instanceof Node && value != null) {
                return value.equals(((Node) obj).value);
            }
            return false;
        }
    }
}
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package TestConcurrent;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.atomic.AtomicReference;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * 尝试用CompareAndSet实现队列 关于队列的队尾,在队尾插入数据,有两步,1.把元队尾队元素指向新队尾元素 2.把队尾指针改为指向新插入元素
 * 由于分两步,所以不能直接使用cas来实现,又因为执行第一步后队尾指针指向的元素不在是队尾元素(该元素不指向null),所以可以其他线程可以判断
 */
public class TestConcurrentQueue {

//使用AtomicReference、构建Node类型的原子变量,代表当前栈顶
    Node dummy = new Node();
    AtomicReference<Node> head = new AtomicReference<Node>();
    AtomicReference<Node> tail = new AtomicReference<Node>();

    public TestConcurrentQueue() {
        AtomicReference<Node> tem = new AtomicReference<Node>(dummy);
        head.set(new Node(tem, ""));
        tail.set(new Node(tem, ""));
    }

    public void push(Object value) {
        while (true) {
            Node curTail = tail.get();
            Node tailNext = curTail.next.get();
            if (tailNext != null) {//处于中间状态
                //帮助执行吧队尾指针指向现在队尾的工作
                tail.compareAndSet(curTail, tailNext);
            } else {//静止状态
                curTail.next.compareAndSet(null, new Node(null, value));
                tail.compareAndSet(curTail, tailNext);
                return;
            }
        }
    }

    public Object pop() {//当删除的是最后一个元素,与插入并发执行时应该更为复杂,暂不管
//        while (true) {
//            Node first = dummy.next.get();
//            if (first == null) {
//                try {
//                    Thread.sleep(Double.valueOf(Math.random() * 1000).longValue());
//                    continue;
//                } catch (InterruptedException ex) {
//                    Logger.getLogger(TestConcurrentStack.class.getName()).log(Level.SEVERE, null, ex);
//                }
//            }
//            Node second = first.next.get();
//            if(){
//
//            }
//            if (dummy.next.compareAndSet(first, second)) {
//                return first;
//            }
//        }
        return null;
    }

    public static void main(String args[]) {
        TestConcurrentQueue queue = new TestConcurrentQueue();
        CyclicBarrier barrier = new CyclicBarrier(1000);//保证线程同一时间起跑
        List<Thread> list = new ArrayList();
        for (int i = 0; i < 510; i++) {
            Thread t = new Thread(new pusher(queue, barrier));
            list.add(t);
            t.start();
        }
        for (int i = 0; i < 490; i++) {
            Thread t = new Thread(new poper(queue, barrier));
            list.add(t);
            t.start();
        }
        for (Thread t : list) {
            try {
                t.join();
            } catch (InterruptedException ex) {
                Logger.getLogger(TestConcurrentStack.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        System.out.println("-------以下将打印出当前堆栈中的各个对象-----");
        Node curNode = queue.dummy.next.get();
        int i = 0;
        while (curNode != null) {
            System.out.println("【"
                    + curNode.value + "】");
            curNode = curNode.next.get();
            i++;
        }
        System.out.println("------------------栈中还有【" + i + "】个数据----------------------");
    }

    public static class pusher implements Runnable {

        TestConcurrentQueue stack;
        CyclicBarrier barrier;

        public pusher(TestConcurrentQueue stack, CyclicBarrier barrier) {
            this.stack = stack;
            this.barrier = barrier;
        }

        @Override
        public void run() {
            try {
                barrier.await();
                Thread.sleep(1000);
                this.stack.push(Thread.currentThread().getName() + "插入数据");
            } catch (InterruptedException ex) {
                Logger.getLogger(TestConcurrentStack.class.getName()).log(Level.SEVERE, null, ex);
            } catch (BrokenBarrierException ex) {
                Logger.getLogger(TestConcurrentStack.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

    }

    public static class poper implements Runnable {

        TestConcurrentQueue queue;
        CyclicBarrier barrier;

        public poper(TestConcurrentQueue stack, CyclicBarrier barrier) {
            this.queue = stack;
            this.barrier = barrier;
        }

        @Override
        public void run() {
            try {
                barrier.await();
                Thread.sleep(1000);
                Object value = this.queue.pop();
                if (value != null) {
                    System.out.println(Thread.currentThread().getName() + "删除了数据【"
                            + value + "】");
                } else {
//                    System.out.println(Thread.currentThread().getName() + "当前栈顶为空  【               】 ");
                }
            } catch (InterruptedException ex) {
                Logger.getLogger(TestConcurrentStack.class.getName()).log(Level.SEVERE, null, ex);
            } catch (BrokenBarrierException ex) {
                Logger.getLogger(TestConcurrentStack.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

    }

    /**
     * 代表节点
     */
    public static class Node {

        AtomicReference<Node> next = new AtomicReference<Node>();
        public Object value;

        public Node() {

        }

        public Node(AtomicReference<Node> next, Object value) {
            this.next = next;
            this.value = value;
        }

        @Override
        public boolean equals(Object obj) {
            if (obj instanceof Node && value != null) {
                return value.equals(((Node) obj).value);
            }
            return false;
        }
    }
}

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package TestConcurrent;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * 尝试使用AtomicReferenceFieldUpdater的compareAndSet实现同步的堆栈
 * 注意一点CAS对比锁的使用,在中低级的竞争环境下可以提供更高的效率
 * AtomicReferenceFieldUpdater可以以CompareAndSet的方式更新【volatil】变量
 */
public class TestConcurrentStackFiledUpdater {

//使用AtomicReference、构建Node类型的原子变量,代表当前栈顶
    volatile Node top = new Node();
    private static final AtomicReferenceFieldUpdater<TestConcurrentStackFiledUpdater, Node> topUpdater
            = AtomicReferenceFieldUpdater.newUpdater(TestConcurrentStackFiledUpdater.class, Node.class, "top");

    /**
     * newUpdater public static <U,W> AtomicReferenceFieldUpdater<U,W>
     * newUpdater(Class<U> tclass, Class<W> vclass, String
     * fieldName)使用给定的字段为对象创建和返回一个更新器。需要 Class 参数检查反射类型和一般类型是否匹配。 * 参数: tclass -
     * 保持字段的对象类。 vclass - 该字段的类 fieldName - 要更新的字段名称。
     */
    public TestConcurrentStackFiledUpdater() {
    }

    public void push(Object value) {
        //获得当前top值以使用cas
        Node oldHead;
        Node newHead;
        do {
            oldHead = topUpdater.get(this);
            newHead = new Node(oldHead, value);
        } while (!topUpdater.compareAndSet(this, oldHead, newHead));
    }

    public Object pop() {
        Node oldHead;
        Node newHead = null;
        Boolean result = false;
        do {
            oldHead = topUpdater.get(this);
            if (oldHead == null || oldHead.next == null) {
                try {
                    Thread.sleep(Double.valueOf(Math.random() * 1000).longValue());
                    continue;
                } catch (InterruptedException ex) {
                    Logger.getLogger(TestConcurrentStackFiledUpdater.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
            newHead = oldHead.next;
            result = topUpdater.compareAndSet(this, oldHead, newHead);
        } while (!result);
        return oldHead.value;
    }

    public static void main(String args[]) {
        TestConcurrentStackFiledUpdater stack = new TestConcurrentStackFiledUpdater();
        CyclicBarrier barrier = new CyclicBarrier(1000);//保证线程同一时间起跑
        List<Thread> list = new ArrayList();
        for (int i = 0; i < 510; i++) {
            Thread t = new Thread(new pusher(stack, barrier));
            list.add(t);
            t.start();
        }
        for (int i = 0; i < 490; i++) {
            Thread t = new Thread(new poper(stack, barrier));
            list.add(t);
            t.start();
        }
        for (Thread t : list) {
            try {
                t.join();
            } catch (InterruptedException ex) {
                Logger.getLogger(TestConcurrentStackFiledUpdater.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        System.out.println("-------以下将打印出当前堆栈中的各个对象-----");
        Node curNode = stack.topUpdater.get(stack);
        int i = 0;
        while (curNode != null) {
            System.out.println("【"
                    + curNode.value + "】");
            curNode = curNode.next;
            i++;
        }
        System.out.println("------------------栈中还有【" + i + "】个数据----------------------");
    }

    public static class pusher implements Runnable {

        TestConcurrentStackFiledUpdater stack;
        CyclicBarrier barrier;

        public pusher(TestConcurrentStackFiledUpdater stack, CyclicBarrier barrier) {
            this.stack = stack;
            this.barrier = barrier;
        }

        @Override
        public void run() {
            try {
                barrier.await();
                Thread.sleep(1000);
                this.stack.push(Thread.currentThread().getName() + "插入数据");
            } catch (InterruptedException ex) {
                Logger.getLogger(TestConcurrentStackFiledUpdater.class.getName()).log(Level.SEVERE, null, ex);
            } catch (BrokenBarrierException ex) {
                Logger.getLogger(TestConcurrentStackFiledUpdater.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

    }

    public static class poper implements Runnable {

        TestConcurrentStackFiledUpdater stack;
        CyclicBarrier barrier;

        public poper(TestConcurrentStackFiledUpdater stack, CyclicBarrier barrier) {
            this.stack = stack;
            this.barrier = barrier;
        }

        @Override
        public void run() {
            try {
                barrier.await();
                Thread.sleep(1000);
                Object value = this.stack.pop();
                if (value != null) {
                    System.out.println(Thread.currentThread().getName() + "删除了数据【"
                            + value + "】");
                } else {
//                    System.out.println(Thread.currentThread().getName() + "当前栈顶为空  【               】 ");
                }
            } catch (InterruptedException ex) {
                Logger.getLogger(TestConcurrentStackFiledUpdater.class.getName()).log(Level.SEVERE, null, ex);
            } catch (BrokenBarrierException ex) {
                Logger.getLogger(TestConcurrentStackFiledUpdater.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

    }

    /**
     * 代表节点
     */
    public static class Node {

        public Node next;
        public Object value;

        public Node() {

        }

        public Node(Node next, Object value) {
            this.next = next;
            this.value = value;
        }

        @Override
        public boolean equals(Object obj) {
            if (obj instanceof Node && value != null) {
                return value.equals(((Node) obj).value);
            }
            return false;
        }
    }
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值