一、继承Thread类重写其run方法
1.线程类
public class MyThread extends Thread{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"run方法重写");
}
}
2.测试类
public class MyThreadTest {
@Test
public void test01(){
MyThread thread = new MyThread();
thread.start();
System.out.println(Thread.currentThread().getName());
}
}
3.输出结果
二、实现runable接口
1.结合拉姆达表达式实现
@Test
public void test01() {
Runnable runnable = () -> {
System.out.println(Thread.currentThread().getName());
};
System.out.println(Thread.currentThread().getName());
new Thread(runnable).start();
}
2.输出结果
三、通过线程池创建
可缓存线程池
1.判断线程池中是否存在空闲线程
2.存在则使用
3.不存在则新建
@Test
public void test02() throws InterruptedException {
//创建可缓存线程池
ExecutorService executor = Executors.newCachedThreadPool();
//向线程池中加入任务
executor.execute(()->{
System.out.println("任务一:"+Thread.currentThread().getName());
});
//主线程睡眠1s等待任务一执行完成
Thread.sleep(1000);
executor.execute(()->{
System.out.println("任务二:"+Thread.currentThread().getName());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
executor.execute(()->{
System.out.println("任务三:"+Thread.currentThread().getName());
});
executor.execute(()->{
System.out.println("任务四:"+Thread.currentThread().getName());
});
}
输出结果
定长线程池
1.判断线程池中是否存在空闲线程
2.存在则使用
3.若不存在且线程池已满,则等待线程
@Test
public void test03() throws InterruptedException {
//线程池的线程长度为2
ExecutorService executor= Executors.newFixedThreadPool(2);
executor.execute(()->{
System.out.println("任务一:"+Thread.currentThread().getName());
});
Thread.sleep(2000);
executor.execute(()->{
System.out.println("任务二:"+Thread.currentThread().getName());
});
executor.execute(()->{
System.out.println("任务三:"+Thread.currentThread().getName());
});
executor.execute(()->{
System.out.println("任务四:"+Thread.currentThread().getName());
});
}
这时候如果我们让任务二睡眠10s,任务三睡醒5s,此时任务四无可用线程,需等待任务三执行完成
@Test
public void test03() throws InterruptedException {
//线程池的线程长度为2
ExecutorService executor= Executors.newFixedThreadPool(2);
executor.execute(()->{
System.out.println("任务一:"+Thread.currentThread().getName());
});
//主线程睡眠等待任务一执行完成
Thread.sleep(2000);
executor.execute(()->{
System.out.println("任务二:"+Thread.currentThread().getName());
try {
//任务二占用线程10s
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
executor.execute(()->{
System.out.println("任务三:"+Thread.currentThread().getName());
try {
//任务三占用线程5s
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
executor.execute(()->{
//任务四需等待线程二和三执行完成,不会新建线程
System.out.println("任务四:"+Thread.currentThread().getName());
});
//主线程睡眠30s保证程序不结束
Thread.sleep(30000);
}
输出结果
周期定长性线程池
任务周期性执行
1.判断线程池是否存在空闲线程
2.存在则使用
3.不存在则等待线程池的空闲线程
java8提供的获取时间
public String getLocalDateTime(){
LocalDateTime localDateTime = LocalDateTime.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
return localDateTime.format(formatter);
}
延时执行
@Test
public void test04() throws InterruptedException {
ScheduledExecutorService executor = Executors.newScheduledThreadPool(2);
System.out.println("开始时间"+getLocalDateTime());
//表示延迟五秒执行
executor.schedule(()->{
System.out.println(Thread.currentThread().getName()+": 执行时间"+getLocalDateTime());
},5, TimeUnit.SECONDS);
Thread.sleep(10000);
}
输出结果
周期性执行
@Test
public void test05() throws InterruptedException {
ScheduledExecutorService executor = Executors.newScheduledThreadPool(2);
System.out.println("开始时间"+getLocalDateTime());
/**
* 第一个参数:要执行的具体任务
* 第二个参数:延时执行的数字时长
* 第三个参数:每次执行的间隔时长
* 第四个参数:时长的单位
*/
executor.scheduleAtFixedRate(()->{
System.out.println(Thread.currentThread().getName()+": 执行时间"+getLocalDateTime());
},1,3,TimeUnit.SECONDS);
//主线程睡眠30s保证程序不结束
Thread.sleep(30000);
}
输出结果
单线程线程池
创建一个线程的线程池,保证任务的有序执行
@Test
public void test06() throws InterruptedException {
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.execute(()->{
System.out.println("任务一:"+Thread.currentThread().getName()+": 执行时间"+getLocalDateTime());
});
executor.execute(()->{
System.out.println("任务二:"+Thread.currentThread().getName()+": 执行时间"+getLocalDateTime());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
executor.execute(()->{
System.out.println("任务三:"+Thread.currentThread().getName()+": 执行时间"+getLocalDateTime());
});
executor.execute(()->{
System.out.println("任务四:"+Thread.currentThread().getName()+": 执行时间"+getLocalDateTime());
});
executor.execute(()->{
System.out.println("任务五:"+Thread.currentThread().getName()+": 执行时间"+getLocalDateTime());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
executor.execute(()->{
System.out.println("任务六:"+Thread.currentThread().getName()+": 执行时间"+getLocalDateTime());
});
Thread.sleep(10000);
}
输出结果
推荐使用线程池的方式创建线程,通过线程池的方式创建可重复利用已创建的线程降低线程创建和销毁造成的消耗