Java在处理多线程同步时,采用的同步机制有很多.
在这里总结下,大体都有哪些.
1)synchronized这个修饰符不陌生.
通过synchronized这个可以生成三和中锁.
分别是:
类锁:通过对一个类方法添加synchronized修饰,例如:static synchronized method();
也可以通过synchronized(类名.class)添加同步锁,锁定该类的字节码实现.
对象锁(也称方法锁):通过对一个成员方法添加synchronized修饰,例如:synchronized method();
也可以通过synchronized(this),this代表的就是类对象
私有锁:其定义是通过自定义一个lock,例如Object lock = new Object();
在需要使用私有锁的地方,通过synchronized(lock){}进行代码同步,这种方式,可以将锁细粒度减小.使同步的同时,不至于减少太多的效率
2)有私有锁应运而生的分段锁
分段锁的概念是将一组对象,或一个集合对象,对行锁分配,面每一个锁分配一部分数据,达成更为高效的私有锁变种.
例如:我们在进行多进程操作一个HashMap时,我们可通过synchronized对操作HashMap的方法进行加锁,但是也可以将HashMap改为ConcurrentHashMap(其内部实现了分段锁机制),来实现同步.相比性能而方,肯定是ConcurrentHashMap效率要高于加了synchronized的HashMap.
3)API提供的Lock实现同步锁
java.util.concurrent.locks.Lock接口下,可以看到有三个实现类,分别是:
ReentrantLock;Condition;ReadWriteLock
分别是重入锁,条件锁与读写锁.比如我们用ReentrantLock,实现一个代码块的同步.
class X {
private final ReentrantLock lock = new ReentrantLock();
// ...
public void m() {
lock.lock(); // block until condition holds
try {
// ... method body
finally {
lock.unlock()
}
}
}}
4)通过CountDownLatch将异步线程转为同步线程.
class Driver { // ...
void main() throws InterruptedException {
CountDownLatch startSignal = new CountDownLatch(1);
CountDownLatch doneSignal = new CountDownLatch(N);
for (int i = 0; i < N; ++i) // create and start threads
new Thread(new Worker(startSignal, doneSignal)).start();
doSomethingElse(); // don't let run yet
startSignal.countDown(); // let all threads proceed
doSomethingElse();
doneSignal.await(); // wait for all to finish
}
}
class Worker implements Runnable {
private final CountDownLatch startSignal;
private final CountDownLatch doneSignal;
Worker(CountDownLatch startSignal, CountDownLatch doneSignal) {
this.startSignal = startSignal;
this.doneSignal = doneSignal;
}
public void run() {
try {
startSignal.await();
doWork();
doneSignal.countDown();
} catch (InterruptedException ex) {} // return;
}
void doWork() { ... }
网友评论