快捷搜索:  汽车  科技

多线程从线程原理到实战(多线程的三种创建方式)

多线程从线程原理到实战(多线程的三种创建方式)public void schedule ( TimerTask task Date firstTime long period)第一个task ,要执行的任务(打印系统日志),Date firstTime:第一次开始日期,long period :周期public abstract class TimerTask 可以传入线程对象的构造方法中TimerTsk extends Object implements Runnablepublic abstract void run ();package Timer_; ​ import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Timer; import java.util.Time

1. 多线程的中创建方式
  • 方式一:继承Thread方法
  • 方式二:实现Runnable 接口
  • 方式三:实现Callable接口

因为前面连个之前已经讲过了,所以这里主要强调的是第三种方式创建线程Callable接口时JDK1.8之后新设置的一个接口,主要作用是在重写 call() 方法的时候可以返回参数

package Timer_; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; ​ public class Timer_ { public static void main(String[] args) { // 使用匿名内部类, FutureTask相当于Thread 的作用,new 出来的对象,没有start方法, // 还是要通过new Thread 对象调用start方法来启动线程 FutureTask<String> ft = new FutureTask<>(new Callable<String>() { @Override public String call() throws Exception { Thread.sleep(1000 * 2); System.out.println("MyCall线程开始运行..."); return "返回值!"; } }); Thread td = new Thread(ft); td.start(); ​ String result = null; try { result = ft.get(); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } System.out.println("main线程得到了" result); System.out.println("main线程结束了..."); } }

  • 运行结果:
  • MyCall线程开始运行...
    main线程得到了我是返回值!
  • main线程结束了...
1.1 基本实现步骤:

第一步: FutureTask ft = new FutureTask(new Callable(){ @Override public String call() throws Exception {//run() 自动被调用 System.out.println("MyCall线程开始"); Thread.sleep(1000 * 10); return "返回值!"; } });第二步: Thread ta = new Thread(ft);第三步: ta.start();// 执行call()第四步:Object Object o = ft.get();//处理异常 导致当前线程阻塞 继续执行当前线程第五步: 获取结果处理结果

2. 守护线程
  • 概念:

用户线程: 执行任务,任务完成之后关闭守护线程: 之哟啊有一个用户线程在运行,守护线程就一直运行,比如: GC垃圾回收器守护线程的用法: 线程对象. setDaemon(true);

3. 时钟Timer
  • 作用: 用作周期性业务,比如文件备份,备份日志等

new Timer (true) :守护(守护线程)始终new Timer () 非守护线程

  • 用法

public void schedule ( TimerTask task Date firstTime long period)第一个task ,要执行的任务(打印系统日志),Date firstTime:第一次开始日期,long period :周期public abstract class TimerTask 可以传入线程对象的构造方法中TimerTsk extends Object implements Runnablepublic abstract void run ();

3.1 具体用法-案例
  • 需求分析: 要求写一个守护始终,同步系统时间,每隔5s打印一次系统时间,主线程main每隔 1s 打印一次系统时间,打印30次结束程序。

package Timer_; ​ import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Timer; import java.util.TimerTask; ​ public class Timers_ { public static void main(String[] args) { ​ Timer timer = new Timer(true); // 创建守护时钟 Mytask mytask = new Mytask(); ​ Date time =null; SimpleDateFormat spf = new SimpleDateFormat("yyyy年 MM月 dd日 HH时:mm分:ss秒"); try { time = spf.parse("2022年 08月 10日 22时:05分:50秒"); } catch (ParseException e) { e.printStackTrace(); } ​ timer.schedule(mytask time 1000*5); ​ for (int i = 0; i < 30; i ) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("mian线程执行到" i); } System.out.println("main线程执行结束..."); } } ​ class Mytask extends TimerTask { @Override public void run() { String name = Thread.currentThread().getName(); // HH 是24小时进制,月份MM必须大写 SimpleDateFormat spf = new SimpleDateFormat("yyyy年 MM月 dd日 HH时:mm分:ss秒"); String time = spf.format(new Date()); System.out.println(name "--->" time); } }

运行结果:

多线程从线程原理到实战(多线程的三种创建方式)(1)

例题总结:

这是一个非常有意思的例题,首先考察的是对时间Date类的运行,一定要非常的熟练才行考察对线程的应用,守护始终就是一个扩张,通过运行结果图,我们可以很清楚的看到程序已经实现 了预期效果如果将守护始终配合IO流进行扩展,那么不久可以打印出我们想要的程序运行日志了嘛!还是非常有意思的最后留一个小点,这里Mytask类,非常显眼,可以直接schedule方法中写成匿名内部类,这样看上去更加简洁一些,匿名内部类可以写接口,也可以写抽象方法!!

猜您喜欢: