在前些天的学习中,感觉到线程是非常非常的重要,所以写了一个关于线程调用的问题,具体如下:
现在,有这么个需求,我需要做一个定时器,每1000ms也就是1S响一下,或者说执行我们所给的操作(示例中只是简单的输出了一下)
一般情况的做法是: 我们给出一个线程,让它等待1000ms,完了之后执行我们给的dosomething()方法,用来执行我们的操作;
乍一看,这个处理方法好像没有什么问题,但是仔细想想就有问题了,如果只有一个线程,那么当计时器线程工作的时候,我们只能干等,时间到了才能执行,但是如果这个方法执行比较耗时,我们方法还没完的时候计时器又到了下一个时间点,那么又只能干等着上一次的方法执行完,这样我们的代码效率无疑是非常低效的;
新思路的做法: 我可以给出两个线程,一个是滴答滴答的计时器线程,另一个是worker线程,同时给他们加上一个共同的synchronized (lock);什么意思呢?就是说,我让一个线程专门计时,时间到了,它的任务不是执行dosomething()方法,二是notify(),即唤醒相同对象锁下的线程,也就是唤醒worker,而在worker中执行dosomething()方法,这样的优点在于避免了我们上面提到的错误,同时让代码变得非常高效;
代码示例如下:
Didadida类:
public abstract class Didadida implements Runnable {
private Object lock;
private volatile boolean goon = false;
private long delayTime;
public static final long DEFAULT_TIME = 1000;
public abstract void dosomething();
public Didadida() {
this.lock = new Object();
this.delayTime = DEFAULT_TIME;
}
public Didadida setDelayTime(long delayTime) {
this.delayTime = delayTime;
return this;
}
public void startClock() {
if(goon == true) {
return;
}
goon = true;
new DidaWorker();
new Thread(this,"滴答滴答").start();
}
public void stop() {
if(goon == false) {
return;
}
goon = false;
}
@Override
public void run() {
while(goon) {
synchronized (lock) {
try {
lock.wait(delayTime);
System.out.println(delayTime+"ms到!");
lock.notifyAll();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class DidaWorker implements Runnable{
public DidaWorker() {
new Thread(this,"worker").start();
}
@Override
public void run() {
while(goon) {
synchronized (lock) {
try {
lock.wait();
dosomething();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
Test类:
public class test {
public static void main(String[] args) {
Didadida didadida = new Didadida() {
@Override
public void dosomething() {
System.out.println(System.currentTimeMillis());
}
}.setDelayTime(100);
didadida.startClock();
}
}
截图如下: