一、守护线程
java语言中线程分为两大类:<br /> 一类是:用户线程<br /> 一类是:守护线程(后台线程)<br /> 其中具有代表性的就是:垃圾回收线程(守护线程)。 守护线程的特点:<br /> 一般守护线程是一个死循环,所有的用户线程只要结束,<br /> 守护线程自动结束。<br /> <br /> 注意:主线程main方法是一个用户线程。 守护线程用在什么地方呢?<br /> 每天00:00的时候系统数据自动备份。<br /> 这个需要使用到定时器,并且我们可以将定时器设置为守护线程。<br /> 一直在那里看着,没到00:00的时候就备份一次。所有的用户线程<br /> 如果结束了,守护线程自动退出,没有必要进行数据备份了。
package com.bjpowernode.java.thread;public class ThreadTest14 { public static void main(String[] args) { Thread t = new BakDataThread(); t.setName("备份数据的线程"); //启动线程前,将线程设置为守护线程 t.setDaemon(true); t.start(); //主线程:用户线程 for (int i =0;i<10;i++){ System.out.println(Thread.currentThread().getName()+"--->"+i); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } }}class BakDataThread extends Thread{ @Override public void run() { int i = 0; while (true){ System.out.println(Thread.currentThread().getName()+"--->"+(++i)); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } }}
二、定时器
定时器的作用:<br /> 间隔特定的时间,执行特定的程序。 每周要进行银行账户的总账操作。<br /> 每天要进行数据的备份操作。 在实际的开发中,每隔多久执行一段特定的程序,这种需求是很常见的,<br /> 那么在java中其实可以采用多种方式实现:<br /> <br /> 可以使用sleep方法,睡眠,设置睡眠时间,没到这个时间点醒来,执行<br /> 任务。这种方式是最原始的定时器。(比较low) 在java的类库中已经写好了一个定时器:java.util.Timer,可以直接拿来用。<br /> 不过,这种方式在目前的开发中也很少用,因为现在有很多高级框架都是支持<br /> 定时任务的。 在实际的开发中,目前使用较多的是Spring框架中提供的SpringTask框架,<br /> 这个框架只要进行简单的配置,就可以完成定时器的任务。
package com.bjpowernode.java.thread;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Date;import java.util.Timer;import java.util.TimerTask;public class TimerTest { public static void main(String[] args) throws ParseException { //创建定时器对象 Timer timer = new Timer(); //指定定时任务 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date firstTime = sdf.parse("2022-03-29 02:22:05"); timer.schedule(new LogTimerTask(),firstTime,1000*10); }}//编写一个定时任务类class LogTimerTask extends TimerTask{ @Override public void run() { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String strTime = sdf.format(new Date()); System.out.println(strTime+"成功完成了一次数据备份"); }}
三、实现线程的第三种方式:实现Callable接口。(JDK8新特性。)
这种方式实现的线程可以获取线程的返回值。<br /> 之前讲解的那两种方式是无法获取线程返回值的,因为run方法返回void。 思考:<br /> 系统委派一个线程去执行一个任务,该线程执行完任务之后,可能<br /> 会有一个执行结果,我们怎么能拿到这个执行结果呢?<br /> 使用第三种方式:实现Callable接口方式。

package com.bjpowernode.java.thread;import java.util.concurrent.Callable;import java.util.concurrent.ExecutionException;import java.util.concurrent.FutureTask;/*实现线程的第三种方式Callable接口 */public class ThreadTest15 { public static void main(String[] args) throws ExecutionException, InterruptedException { FutureTask task = new FutureTask(new Callable() { @Override public Object call() throws Exception { //线程执行一个任务,执行之后可能会有一个执行结果 //模拟执行 System.out.println("call method begin"); Thread.sleep(1000*10); System.out.println("call method end"); int a = 100; int b = 200; return a+b; } }); //创建线程对象 Thread t = new Thread(task); t.start(); // Object obj = task.get(); System.out.println("执行结果--"+obj); System.out.println("hel"); }}
四、关于Object类中的wait和notify方法。(生产者和消费者模式!)
1.wait和notify方法不是线程对象的方法,是java中任何一个java对象
都有的方法,因为这两个方式是Object类中自带的。<br /> wait方法和notify方法不是通过线程对象调用,<br /> 不是这样的:t.wait(),也不是这样的:t.notify()..不对。<br />
2.wait()方法作用?
Object o = new Object();<br /> o.wait(); 表示:<br /> 让正在o对象上活动的线程进入等待状态,无期限等待,<br /> 直到被唤醒为止。<br /> o.wait();方法的调用,会让“当前线程(正在o对象上<br /> 活动的线程)”进入等待状态。
3.notify()方法作用?
Object o = new Object();<br /> o.notify(); 表示:<br /> 唤醒正在o对象上等待的线程。<br /> <br /> 还有一个notifyAll()方法:<br /> 这个方法是唤醒o对象上处于等待的所有线程