线程的创建
1.继承 Thread 类
通过继承Thread类并重写其run()方法,可以定义线程的执行体。
然后创建Thread子类的实例,并调用其start()方法来启动线程。
public class MyThread extends Thread {
@Override
public void run() {
// 线程执行的代码
}
}
// 使用方式
MyThread thread = new MyThread();
thread.start();
下面是代码示例demo
class MyThread extends Thread{
@Override
public void run() {
while (true){
System.out.println("hello thread");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
public class demo1 {
public static void main(String[] args) throws InterruptedException {
Thread t = new MyThread();
t.start();
while (true){
System.out.println("hello main");
Thread.sleep(1000);
}
}
}
2.实现Runnable接口
避免了Java单继承的局限性。通过实现Runnable接口的run()方法,可以将线程的任务与代码分离。然后创建Runnable实现类的实例,并将其作为参数传递给Thread类的构造函数来创建线程对象,最后调用start()方法启动线程。
public class MyRunnable implements Runnable {
@Override
public void run() {
// 线程执行的代码
}
}
// 使用方式
MyRunnable runnable = new MyRunnable();
Thread thread = new Thread(runnable);
thread.start();
代码示例demo
class MyRunnable implements Runnable{
@Override
public void run() {
while (true){
System.out.println("hello thread2");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
public class demo2 {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(new MyRunnable());
t.start();
while (true){
System.out.println("hello main2");
Thread.sleep(1000);
}
}
}
3.实现callable接口
Callable接口与Runnable接口类似,但Callable接口定义的方法call()可以返回一个结果,并且可以声明抛出异常。使用Callable和FutureTask,我们可以获取线程执行后的返回值。
Callable 接口只有一个 call() 方法,源码如下:
public interface Callable<V> {
V call() throws Exception;
}
import java.util.concurrent.*;
public class MyCallable implements Callable<String> {
@Override
public String call() throws Exception {
// 线程执行的代码,并返回结果
return "Hello from Callable";
}
}
// 使用方式
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<String> future = executor.submit(new MyCallable());
try {
String result = future.get(); // 获取线程执行结果
System.out.println(result);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
} finally {
executor.shutdown(); // 关闭线程池
}
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
public class TestCallable1 {
public static void main(String[] args) throws InterruptedException, ExecutionException {
CallableDemo callableDemo = new CallableDemo();
FutureTask futureTask = new FutureTask<>(callableDemo);
new Thread(futureTask).start();
List<Integer> lists = (List<Integer>)futureTask.get(); //获取返回值
for (Integer integer : lists) {
System.out.print(integer + " ");
}
}
}
class CallableDemo implements Callable<List<Integer>>{
@Override
public List<Integer> call() throws Exception {
boolean flag = false;
List<Integer> lists = new ArrayList<>();
for(int i = 3 ; i < 100 ; i ++) {
flag = false;
for(int j = 2; j <= Math.sqrt(i) ; j++) {
if(i % j == 0) {
flag = true;
break;
}
}
if(flag == false) {
lists.add(i);
}
}
return lists;
}
}
4.线程池
线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。线程池线程都是后台线程。每个线程都使用默认的ThreadFactory创建一个新线程。通过Executors工厂类的不同方法,我们可以创建不同类型的线程池,例如FixedThreadPool、SingleThreadExecutor和CachedThreadPool等。
创建线程池的四种方式
newCachedThreadPool 创建一个可缓存的线程池,如果线程池长度超过处理需求,可灵活回收空闲线程,若无可回收,则新建线程 newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待 newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行 newSingleThreadExecutor 创建一个单线程化的线程池,它只会唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO,LIFO,优先级)执行
ExecutorService executor = Executors.newFixedThreadPool(10); // 创建一个固定大小的线程池
for (int i = 0; i < 10; i++) {
Runnable worker = new WorkerThread("" + i);
executor.execute(worker); // 提交Runnable任务给线程池执行
}
executor.shutdown(); // 关闭线程池,等待所有任务执行完毕
while (!executor.isTerminated()) {
// 等待所有线程执行完毕
}
线程池核心的参数
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
RejectedExecutionHandler handler) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), handler);
}
一、corePoolSize 线程池核心线程大小
二、maximumPoolSize 线程池最大线程数量
三、keepAliveTime 空闲线程存活时间
四、unit 空闲线程存活时间单位
五、workQueue 工作队列
六、threadFactory 线程工厂
七、handler 拒绝策略
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class TestThreadPool {
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService executorService = Executors.newFixedThreadPool(5);
List<Future<List<Integer>>> ints = new ArrayList<>();
for(int i = 0 ; i < 5; i ++) {
Future<List<Integer>> future = executorService.submit(new Callable<List<Integer>>() {
@Override
public List<Integer> call() throws Exception {
boolean flag = false;
System.out.println(Thread.currentThread().getName()+" ");
List<Integer> lists = new ArrayList<>();
for(int i = 3 ; i < 100 ; i ++) {
flag = false;
for(int j = 2; j <= Math.sqrt(i) ; j++) {
if(i % j == 0) {
flag = true;
break;
}
}
if(flag == false) {
lists.add(i);
}
}
return lists;
}
});
ints.add(future);
}
for (Future<List<Integer>> future : ints) {
System.out.println(future.get());
}
}
}
其他的实现线程的方式
1.匿名内部类创建 Runnable ⼦类对象
public class demo4 {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread((Runnable) () ->{
while (true){
System.out.println("hello thread4");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
});
t.start();
while (true){
System.out.println(" hello main4");
Thread.sleep(1000);
}
}
}
2.lambda 表达式创建 Runnable ⼦类对象
public class demo5 {
public static void main(String[] args) {
Thread t = new Thread(()->{
while (true){
System.out.println("hello thred5");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
});
t.start();
while (true){
System.out.println(" hello main5");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}