当前位置 : 主页 > 网络编程 > net编程 >

剖析java中几种创建线程的几种方式

来源:互联网 收集:自由互联 发布时间:2023-09-03
文章目录 ​​继承Thread​​ ​​实现Runnable接口​​ ​​实现Callable接口​​ ​​new Thread方式的缺点​​ ​​通过线程池创建​​ ​​newSingleThreadExecutor​​ ​​newFixedThreadPool​​


文章目录

  • ​​继承Thread​​
  • ​​实现Runnable接口​​
  • ​​实现Callable接口​​
  • ​​new Thread方式的缺点​​
  • ​​通过线程池创建​​
  • ​​newSingleThreadExecutor​​
  • ​​newFixedThreadPool​​
  • ​​newScheduledThreadPool​​
  • ​​newCachedThreadPool​​
  • ​​线程池的作用​​

继承Thread

public class ThreadTest {
public static void main(String[] args) {
Thread thread1 = new MyThread();
Thread thread2 = new MyThread();
Thread thread3 = new MyThread();

thread1.start();
thread2.start();
thread3.start();
}
}

class MyThread extends Thread{
@Override
public void run() {
System.out.println(this.getName() + " is running。。。");
}
}

剖析java中几种创建线程的几种方式_System

## 匿名内部类创建线程

new Thread(){
@Override
public void run() {
System.out.println("通过匿名内部类创建的线程 is running ...");
}
}.start();

剖析java中几种创建线程的几种方式_ide_02

实现Runnable接口

public class RunnableTest {
public static void main(String[] args) {
Thread thread1 = new Thread(new MyRunnableThread());
Thread thread2 = new Thread(new MyRunnableThread());
Thread thread3 = new Thread(new MyRunnableThread());

thread1.start();
thread2.start();
thread3.start();
}
}

class MyRunnableThread implements Runnable{
@Override
public void run() {
System.out.println(" Runnable thread is running。。。");
}
}

剖析java中几种创建线程的几种方式_ide_03

实现Callable接口

public class CallableTest {
public static void main(String[] args) throws ExecutionException, InterruptedException {
MyCallableThread myCallableThread = new MyCallableThread();
FutureTask<String> ft = new FutureTask<>(myCallableThread);
Thread thread = new Thread(ft);
thread.start();
System.out.println(ft.get());
}
}

class MyCallableThread implements Callable<String>{

@Override
public String call() throws Exception {
return "Callable 线程创建了";
}
}

剖析java中几种创建线程的几种方式_thread_04

new Thread方式的缺点

  • 每次创建线程都要新建对象,性能较差;
  • 线程缺乏统一的管理,线程的可维护性差;
  • 线程不可重用,创建销毁开销较大。

通过线程池创建

newSingleThreadExecutor

创建一个只有一个线程的线程池。

ExecutorService singleExecutorService = Executors.newSingleThreadExecutor();
for(int i=0;i<10;i++){
int index = i;
singleExecutorService.execute(new Runnable() {
@Override
public void run() {
System.out.println("由newSingleThreadExecutor线程池创建了一个线程");
System.out.println(Thread.currentThread().getName() + ":" + index);
}
});
}

剖析java中几种创建线程的几种方式_System_05

可以看到控制台打印结果中只有一种线程工作,结果依次输出,该线程按指定的顺序执行任务。

newFixedThreadPool

创建一个指定大小的线程池(指定的线程个数,即线程最大的并发数)。

ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
for(int i=0;i<10;i++){
int index = i;
fixedThreadPool.execute(new Runnable() {
@Override
public void run() {
System.out.println("由newFixedThreadPool线程池创建了一个线程");
System.out.println(Thread.currentThread().getName() + ":" + index);
}
});
}

剖析java中几种创建线程的几种方式_ide_06

从打印结果中可以看到,一共创建了指定的线程个数(此例为3个)并发的执行任务。

newScheduledThreadPool

创建一个指定大小的线程池,与newFixedThreadPool类似,但它支持定时及周期性任务的执行

ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(3);
for(int i=0;i<10;i++){
int index = i;
// Thread.sleep(1000);
scheduledThreadPool.schedule(new Runnable() {
@Override
public void run() {
System.out.println("由newScheduledThreadPool线程池创建了一个线程");
System.out.println(Thread.currentThread().getName() + ":" + index);
}
},3, TimeUnit.SECONDS);
}

剖析java中几种创建线程的几种方式_thread_07

newCachedThreadPool

创建一个可缓存的线程池,它可以灵活的回收空闲线程或者创建新线程。

ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
for(int i=0;i<5;i++){ //10
int index = i;
cachedThreadPool.execute(new Runnable() {
@Override
public void run() {
System.out.println("由newCachedThreadPool线程池创建了一个线程");
System.out.println(Thread.currentThread().getName() + ":" + index);
}
});
}

剖析java中几种创建线程的几种方式_java_08

当for循环中遍历的次数为10时,一共创建了10个线程执行任务;

剖析java中几种创建线程的几种方式_ide_09


当for循环中遍历的次数为5时,一共创建了5个线程执行任务。

可以看到,当当前并发的任务量不同时,它可以按需创建不同大小的线程池,已达到最佳性能。

线程池的作用

  • 按照系统的环境情况,限制系统中执行线程的数量;
  • 每个工作线程都可以被重复利用,可执行多个任务,从而减少创建和销毁线程的次数;
  • 根据系统的承受能力,调整线程池中工作线程的个数,防止内存消耗过大


网友评论