多线程的问题和CAS

多线程的问题

  • 正确性
    • 安全:竞争条件/死锁
//竞争条件示例:
    private static int counter = 0;

    public static void main(String[] args) throws InterruptedException {

        for (int i = 0; i < 100; i++) {
            new Thread(() -> {
                try {
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                counter++;
            }).start();
        }
        Thread.sleep(100);
        System.out.println(counter);
    }

控制台结果:
95
- 协同:同时、随机执行的线程,如何协同工作?
      - 解决问题的办法:
      1. java原生实现
       1.1 同步: synchronized
       1.2 协同: wait() / notify() / notifyAll()
  • 效率与易用性
    • 执行地越快越好
    • 用起来越不容易出错越好

CAS(compare and swap)

预期值1 -> 新值2 内存中的旧值0
当且仅当更新瞬间, 内存的值 = 预期值 时,才能操作成功;否则,更新失败;

  • 乐观锁:
    我现在追不到你,过一会再来问; = 自旋锁(spin lock);
private static AtomicInteger counter = new AtomicInteger();

    public static void main(String[] args) throws InterruptedException {

        for (int i = 0; i < 100; i++) {
            new Thread(() -> {
                try {
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                increment();
            }).start();
        }
        Thread.sleep(100);
        System.out.println(counter);
    }

    private static void increment(){
        counter.getAndIncrement();
    }
  • 悲观锁:
    我现在追不到你,就阻塞了;
private static int counter = 0;

    public static void main(String[] args) throws InterruptedException {

        for (int i = 0; i < 100; i++) {
            new Thread(() -> {
                try {
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                increment();
            }).start();
        }
        Thread.sleep(100);
        System.out.println(counter);
    }

    private synchronized static void increment(){ //synchronized 悲观锁
        counter++;
    }
  • 潜在问题:
    ABA问题;
    解决方案:时间戳/版本号;

  • 乐观锁 VS 悲观锁实例
    ConcurrentHashMap VS Collections.synchronizedMap / HashTable
    (Collections.synchronizedMap与hashTable基本上在所有的方法上粗暴的加了synchronized)

附:
mutex = lock
java.util.Collections.SynchronizedMap#mutex
来源于: mutual(共享) + exclusive(排他)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。