《七周七并发模型》1. 概述

并发/并行

并发程序含有多个逻辑上的独立执行块,它们可以独立地并行执行,也可以串行执行。

并发是同一时间应对多件事情的能力。

并行是同一时间动手做多件事情的能力。

并发程序的执行通常是不确定的,它会随着事件时序的改变而给出不同的结果。
并行程序可以是确定的。

Java的线程与锁

线程与锁是共享内存模型。

竞态条件

竞态条件(Race Condition):计算的正确性取决于多个线程的交替执行时序时,就会发生竞态条件。

demo:

public class Puzzle{

 static boolean answerReady = false;
 static int answer = 0;

 static Thread t1 = new Thread() {
   public void run(){
     answer = 42;
     answerReady = true;
  }
 };

 static Thread t2 = new Thread(){
   public void run(){
     if(answerReady)
        System.out.println("The meaning of life is: "+ answer);
     else
       System.out.println("I don;t know the answer");
   }  
 };

 public static void main(String[] args) throws InterruptedEcxeption{
   t1.start(); t2.start();
   t1.join();  t2.join();
 }
}

第6行和第7行可能会乱序执行:

  1. 编译器的静态优化可以打乱代码的执行顺序
  2. JVM的动态优化也会打乱代码的执行顺序
  3. 硬件可以通过乱序执行来优化其性能
  4. 有时一个线程产生的修改可能对另一个线程不可见

Java内存模型的基本原则:如果读线程和写线程不进行同步,就不能保证可见性。

死锁

产生死锁的四个必要条件:

(1) 互斥条件:一个资源每次只能被一个进程使用。
(2) 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
(3) 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。
(4) 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

内置锁虽然很方便但限制很多:

  1. 当一个线程因为等待内置锁而进入阻塞之后,就无法中断该线程了;
  2. 尝试获取内置锁时,无法设置超时;
  3. 获得内置锁,必须使用synchronized块。

所以java5 引入了java.util.concurrent包

ReentrantLock和java.utl.concurrent.atomic突破了使用内置锁的限制,利用新的工具可以做到:

  1. 在线程获取锁时中断它;
  2. 设置线程获取锁的超时时间;
  3. 按任意顺序获取和释放锁;
  4. 用条件变量等待某个条件变为真;
  5. 使用原子变量避免锁的使用

你可能感兴趣的:(《七周七并发模型》1. 概述)