参考博客:
- Java创建线程的四种方式:https://blog.csdn.net/weixin_41891854/article/details/81265772
- java创建线程的三种方式及其对比:https://www.cnblogs.com/songshu120/p/7966314.html
1、继承Thread类创建线程类
(1)定义Thread类的子类,并重写该类的run方法,该run方法的方法体就代表了线程要完成的任务。因此把run()方法称为执行体。
(2)创建Thread子类的实例,即创建了线程对象。
(3)调用线程对象的start()方法来启动该线程。
示例代码,如下:
/**
* @ClassName: MyThread
* @Description: TODO(1.继承Thread类创建线程)
* @author lenovo
* @date 2020年4月1日
*
*/
public class MyThread extends Thread {
@Override
public void run() {
System.out.println("1.继承Thread类创建线程。。。");
System.out.println("currentThread:" + Thread.currentThread());
}
public static void main(String[] args) {
MyThread myThread = new MyThread();
myThread.start();
}
}
2、通过Runnable接口创建线程类
(1)定义runnable接口的实现类,并重写该接口的run()方法,该run()方法的方法体同样是该线程的线程执行体。
(2)创建 Runnable实现类的实例,并以此实例作为Thread的target来创建Thread对象,该Thread对象才是真正的线程对象。
(3)调用线程对象的start()方法来启动该线程。
示例代码,如下:
/**
* @ClassName: MyThread1
* @Description: TODO(2.实现Runnable接口,覆写run()方法,创建线程,推荐此方式)
* @author lenovo
* @date 2020年4月1日
*
*/
public class MyThread1 implements Runnable {
@Override
public void run() {
System.out.println("2.实现Runnable接口,覆写run()方法,创建线程,推荐此方式");
}
public static void main(String[] args) {
MyThread1 myThread1 = new MyThread1();
Thread thread = new Thread(myThread1);
thread.start();
}
}
3、通过Callable和Future创建线程
(1)创建Callable接口的实现类,并实现call()方法,该call()方法将作为线程执行体,并且有返回值。
(2)创建Callable实现类的实例,使用FutureTask类来包装Callable对象,该FutureTask对象封装了该Callable对象的call()方法的返回值。(FutureTask是一个包装器,它通过接受Callable来创建,它同时实现了Future和Runnable接口。)
(3)使用FutureTask对象作为Thread对象的target创建并启动新线程。
(4)调用FutureTask对象的get()方法来获得子线程执行结束后的返回值。
示例代码,如下:
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
/**
* @ClassName: MyThread2
* @Description: TODO(3.覆写Callable接口实现多线程(JDK1.5))
* @author lenovo
* @date 2020年4月3日
*
*/
public class MyThread2 {
public static void main(String[] args) throws InterruptedException, ExecutionException {
Callable<String> callable = new Callable<String>() {
@Override
public String call() throws Exception {
System.out.println("3.覆写Callable接口实现多线程(JDK1.5)");
System.out.println("线程名称:" + Thread.currentThread().getName());
System.out.println("线程优先级:" + Thread.currentThread().getPriority());
System.out.println("线程组名称:" + Thread.currentThread().getThreadGroup().getName());
System.out.println(Thread.currentThread());
Thread.sleep(5000);
return "success";
}
};
//可取消的异步计算
FutureTask<String> futureTask = new FutureTask<String>(callable);
Thread thread = new Thread(futureTask, "线程名称--开天辟地");
thread.start();
//获取计算记过
String result = futureTask.get();
System.out.println("result:" + result);
}
}
4.通过线程池启动多线程
通过Executor 的工具类可以创建三种类型的普通线程池和一种定时任务的线程池:
//1.创建固定大小的线程池
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(5);
//2.创建一个单线程化的线程池
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
//3.创建一个可缓存线程池
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
//4.创建一个定长线程池,支持定时及周期性任务执行。
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
示例代码,如下:
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
* @ClassName: MyThread3
* @Description: TODO(4.通过线程池启动多线程)
* @author lenovo
* @date 2020年4月3日
*
*/
public class MyThread3 {
public static void main(String[] args) {
// testFixedThreadPool();
// testSingleThreadExecutor();
// testCachedThreadPool();
testScheduledThreadPool();
}
/**
* @Title: testFixedThreadPool
* @Description: TODO(1.固定大小的线程池)
*/
public static void testFixedThreadPool() {
//创建固定大小的线程池
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(5);
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread());
}
};
for (int i = 0; i < 10; i++) {
fixedThreadPool.execute(runnable);
}
System.out.println("主线程底部");
}
/**
* @Title: testSingleThreadExecutor
* @Description: TODO(2.单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。)
*/
public static void testSingleThreadExecutor() {
//创建一个单线程化的线程池
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
Runnable runnable = new Runnable() {
@Override
public void run() {
Date date = new Date();
String strDateFormat = "yyyy-MM-dd HH:mm:ss.SSSX";
DateFormat dateFormat = new SimpleDateFormat(strDateFormat);
System.out.println(Thread.currentThread() + " : " + dateFormat.format(date) + "\t:" + date.getTime());
}
};
for (int i = 0; i < 10; i++) {
singleThreadExecutor.submit(runnable);
}
System.out.println("主线程底部");
}
/**
* @Title: testCachedThreadPool
* @Description: TODO(3.可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。)
*/
public static void testCachedThreadPool() {
//创建一个可缓存线程池
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
for (int i = 0; i < 10; i++) {
cachedThreadPool.execute(runnable);
}
System.out.println("主线程底部");
}
/**
* @Title: testScheduledThreadPool
* @Description: TODO(定时、周期性任务的线程池)
*/
public static void testScheduledThreadPool() {
//创建一个定长线程池,支持定时及周期性任务执行。
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread());
System.out.println("delay 3 seconds");
}
};
for (int i = 0; i < 10; i++) {
// scheduledThreadPool.submit(runnable);
scheduledThreadPool.schedule(runnable, 3, TimeUnit.SECONDS);
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("主线程底部");
}
}