多线程与高并发编程(一)

一、

  1. Thread.sleep() 当前线程睡眠指定时间后回到就绪状态(回到等待队列)
  2. Thread.yield() 当前线程直接回到就绪状态(回到等到队列)
  3. Thread.join() 让其他线程在此行执行后优先执行,等他执行完了,当前才开始执行
  4. this.getState() 当前线程的状态(六大状态,runnable自己算一种,下图里面最大的块是runnable状态)禁止stop()方法
    多线程与高并发编程(一)
  5. interrupt()在wait,sleep等方法时打断并抛出一个异常,catch这个异常进行处理(比如说睡了2天,你需要打断他)

  注(重点):wait()方法会释放当前的同步锁,其他线程可以抢了,notify()唤醒线程之后需要重新抢锁才能执行锁内部分!!

二、线程三种实现方式
多线程与高并发编程(一)

三、synchronized

  1. 可见性(多线程之间修改互相可见)
  2. 原子性(当前代码块内有线程在执行,其他线程不可进入,锁定的是对象(this / XX.class,普通方法锁this,static方法锁xx.class)而不是代码,在new Object()时,是64位的,头里面有2位markword代表各种的锁,线程来了是得到这个对象而不是锁代码)
      synchronized(this){…}
      synchronized void function(){…}
      相同;
  3. 可重入(synchronized方法中调用另一个synchronized方法是可以的,因为是同一个线程调用m2时发现是自己拿到了这把锁,OK可以进入)
      锁定的方法和非锁定方法可以同时执行(new Thread)。
      synchronized(Object),这里的Object不能用String常量(因为常量都是大家指向同一个区域的,锁定了这个可能别的地方受影响) Integer(因为Integer对象封装时内部进行了处理,值发生改变就会产生一个新的对象) Long等等基础的数据类型…

      程序之中遇见了异常,默认情况下会释放锁,catch了异常不抛出然后让程序继续执行下去即可避免。
      下图中加了synchronized之后就没必要在count前加volatile了,因为synchronized既保证了原子性,有保证了可见性
    多线程与高并发编程(一)

四、synchronized的底层实现

  1. 锁升级
      sync(object)
      偏向锁:当new object时,markword记录这个线程ID(使用偏向锁),如果还是这个线程执行,那么直接放行。
      自旋锁:如果偏向锁有线程争用,升级为自旋锁,自旋锁是消耗CPU资源的。
      重量级锁(OS级别,内核态):自旋锁默认是自旋10次后,如果还得不到这把锁,升级为重量级锁,重量级锁在一个线程得到后,其他的线程回到等待队列,是不占用CPU资源的。
  2. 结论:
    执行时间段(枷锁代码),线程数少,用自旋锁。
    执行时间长,线程数多,用重量级锁。
    锁一般来讲是不能降级的。