继承Thread类
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @BelongsProject: learn1
* @BelongsPackage: PACKAGE_NAME
* @Author: ZhShy
* @CreateTime: 2022-02-07 22:33
* @Description: 继承Thread类创建线程
*/
public class HelloWorldThread extends Thread {
public static void main(String[] args) throws InterruptedException {
System.out.println(printDate() + "----------主线程创建子线程----------");
HelloWorldThread helloWorldThread = new HelloWorldThread();
System.out.println(printDate() + "----------主线程启动子线程----------");
helloWorldThread.start();
System.out.println(printDate() + "----------主线程休眠3秒----------");
Thread.sleep(3000);
System.out.println(printDate() + "----------主线程执行结束----------");
}
@Override
public void run() {
System.out.println(printDate() + "HelloWorldThread线程输出:HelloWorld");
}
private static String printDate() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return sdf.format(new Date());
}
}
执行结果:
2022-02-07 22:39:12----------主线程创建子线程----------
2022-02-07 22:39:12----------主线程启动子线程----------
2022-02-07 22:39:12----------主线程休眠3秒----------
2022-02-07 22:39:12HelloWorldThread线程输出:HelloWorld
2022-02-07 22:39:15----------主线程执行结束----------
实现Runnable接口
实现Runnable接口可以创建一个线程。实现Runnable接口创建线程如下:
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @BelongsProject: learn1
* @BelongsPackage: PACKAGE_NAME
* @Author: ZhShy
* @CreateTime: 2022-02-07 22:41
* @Description: 实现Runnable接口创建线程
*/
public class HelloWorldRunnable implements Runnable {
@Override
public void run() {
System.out.println(printDate() + "HelloWorldThread线程输出:HelloWorld");
}
private static String printDate() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return sdf.format(new Date());
}
public static void main(String[] args) throws InterruptedException {
HelloWorldRunnable helloWorldRunnable = new HelloWorldRunnable();
System.out.println(printDate() + "----------主线程创建子线程----------");
Thread thread = new Thread(helloWorldRunnable);
System.out.println(printDate() + "----------主线程启动子线程----------");
thread.start();
System.out.println(printDate() + "----------主线程休眠3秒----------");
Thread.sleep(3000);
System.out.println(printDate() + "----------主线程执行结束----------");
}
}
执行结果:
2022-02-07 22:43:49----------主线程创建子线程----------
2022-02-07 22:43:49----------主线程启动子线程----------
2022-02-07 22:43:49----------主线程休眠3秒----------
2022-02-07 22:43:49HelloWorldThread线程输出:HelloWorld
2022-02-07 22:43:52----------主线程执行结束----------
实现Callable接口
Callable接口与Runnable接口相比最大的特点是带有返回值。当线程执行后,不需要携带返回值时,可以使用Runnable或Callable接口。当线程执行后,需要携带返回值时,可以使用Callable接口。实现Callable接口创建线程的代码如下:
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
/**
* @BelongsProject: learn1
* @BelongsPackage: PACKAGE_NAME
* @Author: ZhShy
* @CreateTime: 2022-02-07 22:46
* @Description: 实现Callable接口创建线程
*/
public class CalculateCallable {
public static void main(String[] args) {
// FutureTask对象
// Lambda表达式
FutureTask<Integer> task = new FutureTask<>(() -> {
int count = 0;
for (int i = 0; i <= 100; i++) {
count += i;
}
return count;
});
// 创建线程
Thread thread = new Thread(task);
// 启动线程
thread.start();
try {
System.out.println("1 + 2 + 3 + ... + 100 = " + task.get());
} catch (ExecutionException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
执行结果:
1 + 2 + 3 + ... + 100 = 5050
线程池
在企业开发中,一般使用线程池管理线程,而不是直接创建线程。因为频繁地创建和销毁线程以及创建过多的线程都会对系统性能造成影响。线程池使用方式如下:
import javax.print.attribute.standard.RequestingUserName;
import java.security.spec.NamedParameterSpec;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
/**
* @BelongsProject: learn1
* @BelongsPackage: PACKAGE_NAME
* @Author: ZhShy
* @CreateTime: 2022-02-07 22:52
* @Description: 使用线程池管理线程
*/
public class ThreadPoolDemo {
public static void main(String[] args) {
// 核心线程池大小
int corePoolSize = 2;
// 核心线程池的最大线程数
int maxPoolSize = 4;
// 线程最大空闲时间
long keepAliveTime = 10;
// 时间单位
TimeUnit unit = TimeUnit.SECONDS;
// 阻塞队列容量为2
BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(2);
// 线程创建工厂
ThreadFactory threadFactory = new NameThreadFactory();
// 线程池拒绝策略
RejectedExecutionHandler handler = new MyIgnorePolicy();
ThreadPoolExecutor executor = null;
try {
executor = new ThreadPoolExecutor(corePoolSize,
maxPoolSize, keepAliveTime, unit,
workQueue, threadFactory, handler);
executor.prestartAllCoreThreads();
int count = 10;
for (int i = 1; i < count; i++) {
RunnableTask task = new RunnableTask(String.valueOf(i));
executor.submit(task);
}
} finally {
assert executor != null;
executor.shutdown();
}
}
/**
* 线程工厂
*/
static class NameThreadFactory implements ThreadFactory {
private final AtomicInteger threadId = new AtomicInteger(1);
@Override
public Thread newThread(Runnable runnable) {
Thread t = new Thread(runnable, "线程-" + threadId.getAndIncrement());
System.out.println(t.getName() + "已创建。");
return t;
}
}
public static class MyIgnorePolicy implements RejectedExecutionHandler {
/**
* 可做日志记录等
*
* @param runnable
* @param e
*/
private void doLog(Runnable runnable, ThreadPoolExecutor e) {
System.err.println(e.toString() + runnable.toString() + "rejected");
}
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
}
}
static class RunnableTask implements Runnable {
private String name;
public RunnableTask(String name) {
this.name = name;
}
@Override
public void run() {
try {
System.out.println(this.toString() + " is running!");
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public String toString() {
return "RunnableTask[name=" + name + "]";
}
}
}
执行结果:
线程-1已创建。
线程-2已创建。
线程-3已创建。
线程-4已创建。
RunnableTask[name=1] is running!
RunnableTask[name=3] is running!
RunnableTask[name=6] is running!
RunnableTask[name=2] is running!
RunnableTask[name=4] is running!
RunnableTask[name=5] is running!