Java多线程的创建和启动

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Milogenius/article/details/89418793

在这里插入图片描述

导读
闲暇周末,怎能懒惰?乘此风和日丽之日,来死磕一下java多线程的创建和启动

一.继承Thread类和重写run()方法

public class MyThread extends Thread {

    private String name;
    public MyThread(String name) {
        this.name = name;
    }

    @Override
    public void run() {
        System.out.println(name+"执行了");

    }

    public static void main(String[] args) {
        MyThread mt1 = new MyThread("线程1");
        mt1.start();

    }
}

执行结果:
在这里插入图片描述

二.实现Runnable接口

public class MyRunnable implements Runnable{

    private String name;

    public MyRunnable(String name) {
        this.name = name;
    }

    @Override
    public void run() {
        System.out.println(name+"执行了");
    }

    public static void main(String[] args) {
        MyRunnable runnable = new MyRunnable("线程2");
        Thread thread = new Thread(runnable);
        thread.start();
    }
}

执行结果:
在这里插入图片描述

三.匿名内部类+Lambda表达式

public class InnerClass {

    public static void main(String[] args) {
        //方式1:相当于继承了Thread类,作为子类重写run()实现
        new Thread() {
            public void run() {
                System.out.println("匿名内部类创建线程方式1..." + Thread.currentThread().getName());
            }
        }.start();

        //方式2:实现Runnable,Runnable作为匿名内部类
        new Thread(new Runnable() {
            public void run() {
                System.out.println("匿名内部类创建线程方式2..." + Thread.currentThread().getName());
            }
        }).start();

        //方式3:Lambda表达式创建线程
        new Thread(() -> {
            System.out.println("Lambda表达式创建线程方式..." + Thread.currentThread().getName());
        }).start();

    }
}

执行结果:
在这里插入图片描述

四.线程池方式

public class ThreadPool {

    public static void main(String[] args) {
        //创建一个可缓存的线程池
        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(4);
        for (int i = 0; i < 10; i++) {
            final int index = i;
            fixedThreadPool.execute(new Runnable() {
                public void run() {
                    try {
                        System.out.println(index+ " "+Thread.currentThread().getName()+" "+ DateUtils.getNowDate());
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
        fixedThreadPool.shutdown();
    }

}

执行结果:
在这里插入图片描述

  • newCachedThreadPool

    创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。

  • newFixedThreadPool

    创建一个指定工作线程数量的线程池。每当提交一个任务就创建一个工作线程,如果工作线程数量达到线程池初始的最大数,则将提交的任务存入到池队列中。FixedThreadPool是一个典型且优秀的线程池,它具有线程池提高程序效率和节省创建线程时所耗的开销的优点。但是,在线程池空闲时,即线程池中没有可运行任务时,它不会释放工作线程,还会占用一定的系统资源。

  • newSingleThreadExecutor

    创建一个单线程化的Executor,即只创建唯一的工作者线程来执行任务,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。如果这个线程异常结束,会有另一个取代它,保证顺序执行。单工作线程最大的特点是可保证顺序地执行各个任务,并且在任意给定的时间不会有多个线程是活动的。

  • newScheduleThreadPool

    建一个定长的线程池,而且支持定时的以及周期性的任务执行,支持定时及周期性任务执行。

五.Callable、Future和FutureTask方式

继承Thread类和实现了Runnable接口这2种方式创建线程都有一个缺陷就是:在执行完任务之后无法获取执行结果。
自从Java 1.5开始,就提供了CallableFuture,通过它们可以在任务执行完毕之后得到任务执行结果。
更多内容请大家学习这篇博客,写的非常棒.Java并发编程:Callable、Future和FutureTask

public class CallableTest {

    public static void main(String[] args) {
        ExecutorService executor = Executors.newCachedThreadPool();
        MyCallable task = new MyCallable();
        Future<Integer> result = executor.submit(task);
        executor.shutdown();

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        }

        System.out.println("主线程在执行任务");

        try {
            System.out.println("task运行结果"+result.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

        System.out.println("所有任务执行完毕");
    }
}

public class MyCallable implements Callable<Integer> {

        @Override
        public Integer call() throws Exception {
            System.out.println("子线程在进行计算");
            Thread.sleep(3000);
            int sum = 0;
            for(int i=0;i<100;i++)
                sum += i;
            return sum;
        }

}

总结

综上所述,我们总结了Java日常开发中多线程创建的多种方式和启动方式.若大家有好的办法,请在评论里面留言.

返回专栏目录

猜你喜欢

转载自blog.csdn.net/Milogenius/article/details/89418793
今日推荐