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

来源:互联网 发布:淘宝开店要押金吗 编辑:程序博客网 时间:2024/06/05 19:14
原子变量与非阻塞同步机制
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
原创粉丝点击