一、守护线程

  1. java语言中线程分为两大类:<br /> 一类是:用户线程<br /> 一类是:守护线程(后台线程)<br /> 其中具有代表性的就是:垃圾回收线程(守护线程)。
  2. 守护线程的特点:<br /> 一般守护线程是一个死循环,所有的用户线程只要结束,<br /> 守护线程自动结束。<br /> <br /> 注意:主线程main方法是一个用户线程。
  3. 守护线程用在什么地方呢?<br /> 每天00:00的时候系统数据自动备份。<br /> 这个需要使用到定时器,并且我们可以将定时器设置为守护线程。<br /> 一直在那里看着,没到00:00的时候就备份一次。所有的用户线程<br /> 如果结束了,守护线程自动退出,没有必要进行数据备份了。
  1. package com.bjpowernode.java.thread;
  2. public class ThreadTest14 {
  3. public static void main(String[] args) {
  4. Thread t = new BakDataThread();
  5. t.setName("备份数据的线程");
  6. //启动线程前,将线程设置为守护线程
  7. t.setDaemon(true);
  8. t.start();
  9. //主线程:用户线程
  10. for (int i =0;i<10;i++){
  11. System.out.println(Thread.currentThread().getName()+"--->"+i);
  12. try {
  13. Thread.sleep(1000);
  14. } catch (InterruptedException e) {
  15. e.printStackTrace();
  16. }
  17. }
  18. }
  19. }
  20. class BakDataThread extends Thread{
  21. @Override
  22. public void run() {
  23. int i = 0;
  24. while (true){
  25. System.out.println(Thread.currentThread().getName()+"--->"+(++i));
  26. try {
  27. Thread.sleep(1000);
  28. } catch (InterruptedException e) {
  29. e.printStackTrace();
  30. }
  31. }
  32. }
  33. }

二、定时器

  1. 定时器的作用:<br /> 间隔特定的时间,执行特定的程序。
  2. 每周要进行银行账户的总账操作。<br /> 每天要进行数据的备份操作。
  3. 在实际的开发中,每隔多久执行一段特定的程序,这种需求是很常见的,<br /> 那么在java中其实可以采用多种方式实现:<br /> <br /> 可以使用sleep方法,睡眠,设置睡眠时间,没到这个时间点醒来,执行<br /> 任务。这种方式是最原始的定时器。(比较low
  4. java的类库中已经写好了一个定时器:java.util.Timer,可以直接拿来用。<br /> 不过,这种方式在目前的开发中也很少用,因为现在有很多高级框架都是支持<br /> 定时任务的。
  5. 在实际的开发中,目前使用较多的是Spring框架中提供的SpringTask框架,<br /> 这个框架只要进行简单的配置,就可以完成定时器的任务。
  1. package com.bjpowernode.java.thread;
  2. import java.text.ParseException;
  3. import java.text.SimpleDateFormat;
  4. import java.util.Date;
  5. import java.util.Timer;
  6. import java.util.TimerTask;
  7. public class TimerTest {
  8. public static void main(String[] args) throws ParseException {
  9. //创建定时器对象
  10. Timer timer = new Timer();
  11. //指定定时任务
  12. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  13. Date firstTime = sdf.parse("2022-03-29 02:22:05");
  14. timer.schedule(new LogTimerTask(),firstTime,1000*10);
  15. }
  16. }
  17. //编写一个定时任务类
  18. class LogTimerTask extends TimerTask{
  19. @Override
  20. public void run() {
  21. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  22. String strTime = sdf.format(new Date());
  23. System.out.println(strTime+"成功完成了一次数据备份");
  24. }
  25. }

三、实现线程的第三种方式:实现Callable接口。(JDK8新特性。)

  1. 这种方式实现的线程可以获取线程的返回值。<br /> 之前讲解的那两种方式是无法获取线程返回值的,因为run方法返回void
  2. 思考:<br /> 系统委派一个线程去执行一个任务,该线程执行完任务之后,可能<br /> 会有一个执行结果,我们怎么能拿到这个执行结果呢?<br /> 使用第三种方式:实现Callable接口方式。

image.png

  1. package com.bjpowernode.java.thread;
  2. import java.util.concurrent.Callable;
  3. import java.util.concurrent.ExecutionException;
  4. import java.util.concurrent.FutureTask;
  5. /*
  6. 实现线程的第三种方式
  7. Callable接口
  8. */
  9. public class ThreadTest15 {
  10. public static void main(String[] args) throws ExecutionException, InterruptedException {
  11. FutureTask task = new FutureTask(new Callable() {
  12. @Override
  13. public Object call() throws Exception {
  14. //线程执行一个任务,执行之后可能会有一个执行结果
  15. //模拟执行
  16. System.out.println("call method begin");
  17. Thread.sleep(1000*10);
  18. System.out.println("call method end");
  19. int a = 100;
  20. int b = 200;
  21. return a+b;
  22. }
  23. });
  24. //创建线程对象
  25. Thread t = new Thread(task);
  26. t.start();
  27. //
  28. Object obj = task.get();
  29. System.out.println("执行结果--"+obj);
  30. System.out.println("hel");
  31. }
  32. }

四、关于Object类中的wait和notify方法。(生产者和消费者模式!)

1.wait和notify方法不是线程对象的方法,是java中任何一个java对象

  1. 都有的方法,因为这两个方式是Object类中自带的。<br /> wait方法和notify方法不是通过线程对象调用,<br /> 不是这样的:t.wait(),也不是这样的:t.notify()..不对。<br />

2.wait()方法作用?

  1. Object o = new Object();<br /> o.wait();
  2. 表示:<br /> 让正在o对象上活动的线程进入等待状态,无期限等待,<br /> 直到被唤醒为止。<br /> o.wait();方法的调用,会让“当前线程(正在o对象上<br /> 活动的线程)”进入等待状态。

3.notify()方法作用?

  1. Object o = new Object();<br /> o.notify();
  2. 表示:<br /> 唤醒正在o对象上等待的线程。<br /> <br /> 还有一个notifyAll()方法:<br /> 这个方法是唤醒o对象上处于等待的所有线程