Java之实现多线程
保证同步的几种方法:
(1) 同步方法,synchronized 关键字修饰方法。由于Java中的每个对象都有一个内置锁,当用该关键词修饰时,内置锁会保护整个方法。在调用该方法前,需要获得内置锁,否则就处于阻塞状态。
1 public synchronized void add(int num){ 2 count+=num; 3 }
(2)同步代码块,synchronized 关键字修饰语句块。修饰后的语句块会自动被加上内置锁,从而实现同步。
1 public void add(int num){ 2 synchronized(this){ 3 count+=num; 4 } 5 }
(3)特殊域变量(volatile)实现线程同步
a.volatile关键字为域变量的访问提供了一种免锁机制
b.使用volatile修饰域相当于告诉虚拟机该域可能会被其他线程更新
c.因此每次使用该域就要重新计算,而不是使用寄存器中的值
d.volatile不会提供任何原子操作,它也不能用来修饰final类型的变量
private volatile int nums=0; public void add(int num){ nums+=num; }
(4)ReentrantLock类是可重入、互斥、实现了Lock接口的锁,它与使用synchronized方法和快具有相同的基本行为和语义,并且扩展了其能力。
ReenreantLock类的常用方法有:
ReentrantLock() : 创建一个ReentrantLock实例
lock() : 获得锁
unlock() : 释放锁
注:ReentrantLock()还有一个可以创建公平锁的构造方法,但由于能大幅度降低程序运行效率,不推荐使用
private int nums=0; private Lock lock=new ReentrantLock(); public void add(int num){ lock.lock(); try { nums+=num; } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ lock.unlock(); } }
(5)局部变量实现线程同步
private static ThreadLocal<Integer> nums=new ThreadLocal<Integer>(){ protected Integer initialValue(){ return 0; } }; public void add(int num){ nums.set(nums.get()+num); }