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

x33g5p2x  于2021-12-09 转载在 Java  
字(3.1k)|赞(0)|评价(0)|浏览(445)

继承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。。。");
    }
}

匿名内部类创建线程

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

实现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。。。");
    }
}

实现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 线程创建了";
    }
}

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);
                }
            });
        }


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

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);
                }
            });
        }


从打印结果中可以看到,一共创建了指定的线程个数(此例为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);
        }

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);
                }
            });
        }


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

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

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

线程池的作用

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

相关文章