• 并发案例(二)


    1.非线程安全
        main线程更新ready址 , ReaderThread 线程持续检测ready状态 ,直到ready为true.
        正常来讲,程序会输出42 ;但也有可能输出0 , 甚至可能程序复发终止。
            输出0: 
     
    @NotSafeThread
     
     
     
     
    public class NoVisibility {
        private static boolean ready;
        private static int number;
     
     
        private static class ReaderThread extends Thread {
            public void run() {
     
                while (!ready)
                    Thread.yield();
     
                System.out.println(number);
            }
     
        }
     
        public static void main(String[] args) {
            new ReaderThread().start();
            number = 42;
            ready = true;
     
        }
     }
     
     
     
     
     
     
    @NotThreadSafe
    public class MutableInteger {
     
        private int value;
     
        public int  get() { return value; }
     
        public void set(int value) { this.value = value; }
    }
     
     
     
     
     
     
     
     
     
     
     
     
    @ThreadSafe
    public class SynchronizedInteger {
     
        @GuardedBy("this") private int value;
     
        public synchronized int get() { return value; }
     
        public synchronized void set(int value) { this.value = value; }
    }
     
     
     
     
    @NotThreadSafe
     
     
     
     
    class UnsafeStates {
        private String[] states = new String[] {
     
            "AK", "AL" ...
        };
     
        public String[] getStates() { return states; }
    }
     
     
     
     
     
     
    @NotSafeThread
     
     
     
     
     
     
     
     
     
    public class ThisEscape {
        public ThisEscape(EventSource source) {
     
     
     
     
     
     
     
     
     
     
    source.registerListener(
        new EventListener() {
     
            public void onEvent(Event e) {
                doSomething(e);
     
    } });
     
     
     
     
    } }
     
     
     
     
     
     
     
     
     
    临时阻塞 
        这个技术尽量少用,比较脆弱。应当使用更加健壮的 栈阻塞 或者是 ThreadLocal
    @SafeThread
     
     
     
     
    public class SafeListener {
        private final EventListener listener;
     
        private SafeListener() {
            listener = new EventListener() {
     
                public void onEvent(Event e) {
                    doSomething(e);
     
    } };
     
    }
     
        public static SafeListener newInstance(EventSource source) {
            SafeListener safe = new SafeListener();
            source.registerListener(safe.listener);
            return safe;
     
    } }
     
     
     
     
    栈阻塞 
        通过 局部变量(local variables) —— 本例中是局部的原始变量, 运行在线程的栈上 ,不会和别的线程共享,来保证线程安全。
     
     
     
     
     
    public int loadTheArk(Collection<Animal> candidates) {
        SortedSet<Animal> animals;
        int numPairs = 0;
        Animal candidate = null;
     
        // animals confined to method, don't let them escape!
        animals = new TreeSet<Animal>(new SpeciesGenderComparator());
        animals.addAll(candidates);
        for (Animal a : animals) {
     
            if (candidate == null || !candidate.isPotentialMate(a))
                candidate = a;
     
            else {
                ark.load(new AnimalPair(candidate, a));
                ++numPairs;
                candidate = null;
     
    } }
     
        return numPairs;
    }
     
     
     
     
     
     
    利用ThreadLocal保证线程安全
    以jdbc connection 为例,每个线程一个connection 。
     
     
     
     
    private static ThreadLocal<Connection> connectionHolder
        = new ThreadLocal<Connection>() {
     
            public Connection initialValue() {
                return DriverManager.getConnection(DB_URL);
     
    } };
     
    public static Connection getConnection() {
        return connectionHolder.get();
     
    }
     
     
     
     
     
     
     
     
    @Immutable
    public final class ThreeStooges {
     
        private final Set<String> stooges = new HashSet<String>();
     
        public ThreeStooges() {
            stooges.add("Moe");
            stooges.add("Larry");
            stooges.add("Curly");
     
    }
     
        public boolean isStooge(String name) {
            return stooges.contains(name);
     
    } }
     
     
  • 相关阅读:
    Promise前期准备---区别实例对象与函数对象
    es6之函数参数默认值、字符串方法、for of
    es6之剩余和扩展参数
    es6之解构赋值
    es6之set和map
    前端知识点总结
    jQuery的12种选择器
    前端面试总结
    Closure
    PHP 中 16 个魔术方法详解
  • 原文地址:https://www.cnblogs.com/lmxxlm-123/p/11131915.html
Copyright © 2020-2023  润新知