相对于synchronized机制,Lock的锁机制更加的灵活,并且能够实现有选择性地进行线程通知。因此相比于重量级的synchronized机制,Lock机制能进一步的缩小同步区域,并有选择性的通知唤醒线程。同时,本文也对Android中常用的定时器Timer的用法进行了总结。
1. Lock的使用
常规用法,利用Condition类与ReentrantLock类,实现代码的同步
public class MyService {
private Lock lock = new ReentrantLock();
public Condition condition = lock.newCondition();
public void await() {
try {
lock.lock();
System.out.println(" await 时间为"+System.currentTimeMillis());
condition.await();
} catch(InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void signal() {
try {
lock.lock();
System.out.println("signal 时间为"+System.currentTimeMillis());
condition.signal();
} finally {
lock.unlock();
}
}
}
由Lock实现同步锁机制,由Condition实现P\V操作,由于Condition对象可以唤醒部分指定线程,有助于提升程序运行的效率。
利用lock机制,实现生产者/消费者问题
public class MyService {
private ReentrantLock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
private boolean hasValue = false;
public void set() {
lock.lock();
while(hasValue == true){
try {
condition.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("打印11111");
hasValue = true;
condition.signal();
lock.unlock();
}
public void get() {
lock.lock();
while(hasValue == false){
try {
condition.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("打印22222");
hasValue = false;
condition.signal();
lock.unlock();
}
}
注:Lock锁机制中存在“公平锁”与“非公平锁”之分,公平锁表示线程获取锁的顺序是按照线程加锁的顺序来分配的,非公平锁就是一种获取锁的抢占机制,是随机获得锁的。具体由创建ReentrantLock对象时传入的true和false进行区分。
2. 定时器Timer
定时器的概念即可理解为windows下的定时任务功能,使得任务可以在指定时间上运行。且定时器的使用主要依赖于schedule方法。
public class Run1 {
private static Timer timer = new Timer(true);
static public class MyTask extends TimerTask{
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println(" 运行了!时间为:"+new Date());
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
MyTask task = new MyTask();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String dateString = "2017-11-6 15:41:00";
Date dateRef = sdf.parse(dateString);
System.out.println("字符串时间:"+dateRef.toLocaleString()+" 当前时间:"+new Date().toString());
timer.schedule(task, dateRef);
} catch(ParseException e) {
e.printStackTrace();
}
}
}
同时timer.schedule方法的第三个参数long period可以指定每隔period的时间间隔,执行以此task