zoukankan      html  css  js  c++  java
  • java多线程

    线程概述

    1.线程的状态

    • NEW:新建的线程,尚未执行

    • Runnable:运行中的线程,正在执行run方法

    • Blocked:阻塞等待,因某些操作被阻塞而挂起

    • Waiting:运行中的线程,因为某些操作在等待中

    • TimeWaiting:超时等待,因为执行sleep()方法正在计时等待

    • Terminated:线程已终止 调用interrupt()方法,可以中断方法

    • blocked和waiting的区别

      • block状态是线程阻塞在进入synchronized修饰的方法或代码块时的状态。
      • waiting可以通过object.join(),wait()方法达到,表示等待object线程结束,
      • block状态是处于wait状态线程的必经之路
    • stop和interrupt的区别?

      • interrupt触发异常,线程可以无视这个通知
      • stop直接终止线程,并释放锁

    线程协调问题

    多线程协调原则

    当条件不满足时,线程进入等待状态;当条件满足时,线程被唤醒,继续执行任务

    • 使用this.wait()进入等待状态,wait()方法必须在当前获取的锁对象上调用,只有在synchronized块中才能调用wait,wait方法在调用后会释放锁
    • this.notifyAll(); // 唤醒在this锁等待的线程
    • 已唤醒的线程还需要重新获得锁后才能继续执行

    ReentrantLock

    java.util.concurrent.locks包提供的ReentrantLock用于替代synchronized加锁

    private final Lock lock = new ReentrantLock();
    private final Condition condition = lock.newCondition();
    await()会释放当前锁,进入等待状态;
    signal()会唤醒某个等待线程;
    signalAll()会唤醒所有等待线程;
    唤醒线程从await()返回后需要重新获得锁。
    

    ReadWriteLock

    • ReadWriteLock可以提高读取效率:
    • ReadWriteLock只允许一个线程写入;
    • ReadWriteLock允许多个线程在没有写入时同时读取;
    • ReadWriteLock适合读多写少的场景。

    StampedLock

    • 提供了乐观读锁,可取代ReadWriteLock以进一步提升并发性能

    Atomic类

    使用java.util.concurrent.atomic提供的原子操作可以简化多线程编程:

    • 原子操作实现了无锁的线程安全;
    • 适用于计数器,累加器等。

    关键字

    volatile

    用于线程间共享的变量,
    告诉虚拟机,每次访问变量时,总是获取主内存的最新值;每次修改变量后,立刻回写到主内存。关键字解决的是可见性问题:当一个线程修改了某个共享变量的值,其他线程能够立刻看到修改后的值

    synchronized

    修饰方法时,锁住的是整个对象

    可重入锁

    获取锁的时候,获取锁的记录次数+1,退出时-1,直到等于0,才时真正的释放锁

    死锁

    一个线程获取锁后,再继续获取另外一个锁,这个锁被另一个线程获取过,就会造成死锁,没有任何机制能解除死锁,只能强制结束JVM进程,

    避免死锁的方式就是获取锁的顺序要一致

    CAS:

    • Compare and Set 底层也是java调用汇编指令进行锁的操作
    public int incrementAndGet(AtomicInteger var) {
        int prev, next;
        do {
            prev = var.get();
            next = prev + 1;
        } while ( ! var.compareAndSet(prev, next));
        return next;
    }
    在这个操作中,如果AtomicInteger的当前值是prev,那么就更新为next,返回true。如果AtomicInteger的当前值不是prev,就什么也不干,返回false。通过CAS操作并配合do ... while循环,即使其他线程修改了AtomicInteger的值,最终的结果也是正确的。
    
  • 相关阅读:
    Java实现 LeetCode 50 Pow(x,n)
    Java实现 LeetCode 50 Pow(x,n)
    Java实现 LeetCode 49 字母异位词分组
    Java实现 LeetCode 49 字母异位词分组
    Java实现 LeetCode 49 字母异位词分组
    Java实现 LeetCode 48 旋转图像
    Java实现 LeetCode 48 旋转图像
    Java实现 LeetCode 48 旋转图像
    Java实现 LeetCode 47 全排列 II(二)
    Java实现 LeetCode 47 全排列 II(二)
  • 原文地址:https://www.cnblogs.com/rise0111/p/13565910.html
Copyright © 2011-2022 走看看