为了保证线程的安全,主要有目前了解到了有一下几个方面:
synchronized 是很多地方都可以用到的,不过这个是比较重量级的
volatile 轻量级,比较局限,修饰修饰变量,保证可见性,并不能保证原子性
AtomicInteger..... 轻量级,比较局限,要用判断等的逻辑操作的时候,Atomic就比较局限了
Lock接口的认识
Lock接口是在JDK5之后才有的,位置如下:
Lock接口和synchronzied关键字对比主要有以下:
Lock需要显示地获取和释放锁,繁琐能让代码更灵活
Synchronized不需要显示地获取和释放锁,简单
简单地说就是,Lock接口对synchronzied关键字是进行一个封装,变得更加强大的一个锁,主要功能有以下:
使用Lock可以方便的实现公平性
非阻塞的获取锁
能被中断的获取锁
超时获取锁
Lock接口的使用例子
我们可以用Java的并发编程:从synchronized保证线程安全的原理这篇文章的例子来做为Lock接口的例子,来看看lock接口是怎么实现线程的安全的。
package com.breakyizhan.thread.t9;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Sequence {
private int value;
Lock lock = new ReentrantLock();
Lock l1 = new ReentrantLock();
/**
* @return
*/
public int getNext() {
lock.lock();
int a = value ++;
lock.unlock();
return a;
}
public static void main(String[] args) {
Sequence s = new Sequence();
new Thread(new Runnable() {
@Override
public void run() {
while(true) {
System.out.println(Thread.currentThread().getName() + " " + s.getNext());
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
while(true) {
System.out.println(Thread.currentThread().getName() + " " + s.getNext());
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
while(true) {
System.out.println(Thread.currentThread().getName() + " " + s.getNext());
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
}