定时器
有时候有这样的需求,希望能定时执行任务,比如3秒后执行,可以通过使用Thread.sleep()来实现:
public class Main {
public static void main(String[] args) {
new TimerTask(() -> System.out.println("我是定时任务"), 3000).start();
}
static class TimerTask{
Runnable task;
long time;
public TimerTask(Runnable runnable, long time){
this.task = runnable;
this.time = time;
}
public void start(){
new Thread(() -> {
try{
Thread.sleep(time);
task.run(); //休眠后运行
}catch (InterruptedException e){
e.printStackTrace();
}
}).start();
}
}
}
提高要求:
能否循环执行一个任务,希望每个1秒执行一次代码。
public class Main {
public static void main(String[] args) {
new TimerTask(() -> System.out.println("我是定时任务"), 3000).start();
}
static class TimerTask{
Runnable task;
long looptime;
public TimerTask(Runnable runnable, long looptime){
this.task = runnable;
this.looptime = looptime;
}
public void start(){
new Thread(() -> {
try{
while(true){
Thread.sleep(looptime);
task.run(); //休眠后运行
}
}catch (InterruptedException e){
e.printStackTrace();
}
}).start();
}
}
}
而Java提供了一套自己的框架用于处理定时任务:
import java.util.Timer;
import java.util.TimerTask;
public class Main {
public static void main(String[] args) {
Timer timer = new Timer(); //创建定时器对象
timer.schedule(new TimerTask() { //注意这个是一个抽象类,不是接口,无法使用lambda表达式简化,只能使用匿名内部类
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
}, 1000); //执行一个延时任务
}
}
我们发现,虽然任务完成了,但是程序并没有停止,因为Timer内存维护了一个任务列和一个工作线程。
有个TimerThread线程没有关闭。
import java.util.Timer;
import java.util.TimerTask;
public class Main {
public static void main(String[] args) {
Timer timer = new Timer(); //创建定时器对象
timer.schedule(new TimerTask() { //注意这个是一个抽象类,不是接口,无法使用lambda表达式简化,只能使用匿名内部类
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
timer.cancel(); //使用cancel结束线程
}
}, 1000); //执行一个延时任务
}
}
添加一行cancel()方法结束。
守护线程
当其他所有的非守护线程结束之后,守护线程是自动结束。也就是说,Java中所有的线程都执行完毕后,守护线程自动结束。因此守护线程不适合IO操作,只适合打打杂。
先了解了解。
集合类的并行方法
在讲解集合类的根接口时,会发现有这样一个方法:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>(Arrays.asList(1, 4, 5, 2, 9, 3, 6, 0));
list
.parallelStream() //获取并行流
.forEach(i -> System.out.println(Thread.currentThread().getName()+ " -> "+i));
}
}
可以发现是多线程执行的。