线程实现计时器,多线程间通信
Timer类:计时器
public class Timer_Test {
public static void main(String[] args) {
new Timer().schedule(new Test(),new Date(),2000);
while(true){
System.out.println(new Date());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
static class Test extends TimerTask{
@Override
public void run() {
System.out.println("时间到了");
}
}
}
- schedule(TimerTask task, Date firstTime, long period)
从指定 的时间开始 ,对指定的任务执行重复的 固定延迟执行 。
三线程间通讯
-
在同步代码块中,用哪个对象锁,就用哪个对象调用wait方法。
创建在Main方法中创建三个线程
代码
public class Demoe {
public static void main(String[] args) {
Print p = new Print();
new Thread() {
@Override
public void run() {
try {
while(true){
p.print1();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}.start();
new Thread() {
@Override
public void run() {
try {
while(true){
p.print2();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}.start();
new Thread() {
@Override
public void run() {
try {
while(true){
p.print3();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}.start();
}
static class Print { //创建内部类并创建三个成员方法,使用WAIT和NOTIFYALL实现线程等待和唤醒
static int flag = 1;
public void print1() throws InterruptedException {
synchronized (this) {
while (flag != 1) { //使用wait保证判断语句能够执行,如果使用if将会直接唤醒线程而跳过判断阶段。
this.wait();
}
System.out.print("a");
System.out.print("b");
System.out.println();
flag = 2;
this.notifyAll();
}
}
public void print2() throws InterruptedException {
synchronized (this) {
while (flag != 2) {
this.wait();
}
System.out.print("1");
System.out.print("2");
System.out.println();
flag = 3;
this.notifyAll();
}
}
public void print3() throws InterruptedException {
synchronized (this) {
while (flag != 3) {
this.wait();
}
System.out.print("A");
System.out.println("B");
flag = 1;
this.notifyAll();
}
}
}
}
- 多个线程通信的问题
- notify()方法是随机唤醒一个线程
- notifyAll()方法是唤醒所有线程
- JDK5之前无法唤醒指定的一个线程
- 如果多个线程之间通信, 需要使用notifyAll()通知所有线程, 用while来反复判断条件
- sleep方法与wait方法区别
- sleep方法有参数,时间结束后,自动醒来
wait可以有参数也可以没有参数,传入就是在参数时间结束时间后等待,不传入直接等待 - sleep方法在同步函数或同步代码块中,不释放锁
wait方法在同步函数或者同步代码块中释放锁
- sleep方法有参数,时间结束后,自动醒来
ReentrantLock实现上述功能
-
可使用if作为判断语句
-
newCondition()
返回Condition用于这种用途实例Lock实例。ReentrantLock r=new ReentrantLock(); Condition c=r.newCondition();
-
使用Lock实例开启锁
r.lock if( flag!=1){ c.await(); }
-
使用指定其他锁开启signal
c.signal();
-
关闭Lock;
-
r.unlock();