• 4、共享模型之管程


    4.1共享带来的问题


    以上的结果可能是正数、负数、零。
    为什么呢?因为 Java 中对静态变量的自增,自减并不是原子操作,要彻底理解,必须从字节码来进行分析











    面向对象改进: 把需要保护的共享变量放入一个类

    class Room {
        int value = 0;
    
        public void increment() {
            synchronized (this) {
                value++;
            }
        }
    
        public void decrement() {
            synchronized (this) {
                value--;
            }
        }
    
        public int get() {
            synchronized (this) {
                return value;
            }
        }
    }
    
    @Slf4j
    public class TestCounterOop {
    
        public static void main(String[] args) throws InterruptedException {
            Room room = new Room();
            
            Thread t1 = new Thread(() -> {
                for (int j = 0; j < 5000; j++) {
                    room.increment();
                }
            }, "t1");
    
            Thread t2 = new Thread(() -> {
                for (int j = 0; j < 5000; j++) {
                    room.decrement();
                }
            }, "t2");
            t1.start();
            t2.start();
    
            t1.join();
            t2.join();
            log.debug("count: {}" , room.get());
        }
    }
    
    


    线程8锁











    成员变量例子

    class ThreadUnsafe {
          ArrayList<String> list = new ArrayList<>();
          public void method1(int loopNumber) {
                for (int i = 0; i < loopNumber; i++) {
                      // { 临界区, 会产生竞态条件
                            method2();
                            method3();
                      // } 临界区
                 }
          }
          private void method2() {
                list.add("1");
           }
          private void method3() {
                list.remove(0);
           }
    }
    
    static final int THREAD_NUMBER = 2;
    static final int LOOP_NUMBER = 200;
    public static void main(String[] args) {
    ThreadUnsafe test = new ThreadUnsafe();
    for (int i = 0; i < THREAD_NUMBER; i++) {
          new Thread(() -> {
                      test.method1(LOOP_NUMBER);
                       }, "Thread" + i).start();
                 }
    }
    


    将list变量改为局部变量

    class ThreadSafe {
          public final void method1(int loopNumber) {
                ArrayList<String> list = new ArrayList<>();
                for (int i = 0; i < loopNumber; i++) {
                      method2(list);
                      method3(list);
                 }
           }
            private void method2(ArrayList<String> list) {
                list.add("1");
            }
            private void method3(ArrayList<String> list) {
                list.remove(0);
           }
    }
    









    实例







    4.5 习题


    4.6 Monitor概念


































    撤销40次后,变为不可偏向状态;20次的时候我是不是偏向错了,40次的时候说明类竞争激烈,不要偏向任何线程了


    4.7 wait notify








    4.8 wait,notify 的正确姿势









  • 相关阅读:
    shell:读取文件的每一行内容并输出
    shell中set命令
    shell中declare命令
    MySQL MID()函数用法
    mysql的取整函数
    二分查找算法
    zookeeper安装和使用
    Redis 集群--------Redis-cluster
    ehcahe + redis 实现多级缓存
    Redis事物
  • 原文地址:https://www.cnblogs.com/xidianzxm/p/13826328.html
Copyright © 2020-2023  润新知