0%

Java多线程

线程与进程区别:

  1. 进程是资源分配的最小单位,线程是CPU调度的最小单位
  2. 一个进程由一个或多个线程组成
  3. 进程之间相互独立,每个进程都有独立的代码和数据空间,但同一进程下的各个线程之间共享进程的代码和内存空间,每个线程有独立的运行栈和程序计数器
  4. 线程上下文切换比进程上下文切换要快得多

线程安全

线程安全:就是说多线程访问同一代码,不会产生不确定的结果。(vector, hashTable是线程安全的, arrayList和 hashMap是不安全的)

  1. synchronized同步方法 即有synchronized关键字修饰的方法。由于java的每个对象都有一个内置锁,当用此关键字修饰方法时,内置锁会保护整个方法。 也可以修饰静态方法,此时如果调用该静态方法,将会锁住整个类
  2. synchronized同步代码块 即有synchronized关键字修饰的语句块。 当一个线程访问object的一个synchronized(this)同步代码块时,它就获得了这个object的对象锁。结果,其它线程对该object对象所有同步代码部分的访问都被暂时阻塞,但仍然可以访问该object中的非synchronized(this)同步代码块。
  3. volatile实现线程同步 用volatile修饰的变量,线程在每次使用变量的时候,都会从主存中读取变量最新值。变量修改后会直接改变主存内容。保证可见性,不能保证原子性
  4. 使用重入锁实现线程同步ReentrantLock ReentrantLock 拥有Synchronized相同的并发性和内存语义,此外还多了 锁投票,定时锁等候和中断锁等候,比如可以放弃锁等待先做别的事情(trylock),而Synchronized不能 synchronized是在JVM层面上实现的,JVM会自动释放锁定,但是使用Lock则不行,lock是通过代码实现的,要保证锁定一定会被释放,就必须将unLock()放到finally{}中 在资源竞争很激烈的情况下,ReetrantLock的性能要优于Synchronized
  5. 使用ThreadLocal管理变量 使用该变量的线程都获得该变量的副本,副本之间相互独立,这样每一个线程都可以随意修改自己的变量副本,而不会对其他线程产生影响。