java创建线程的多种方式

目录

1.继承Thread类,重写它的run方法;

2.实现Runnable接口,实现其run方法;

 3.通过创建FutureTask的对象来实现(带返回值);

 4.通过匿名内部类的方式;

5.线程池的方式;


1.继承Thread类,重写它的run方法;

package classFile;

class MyThread extends Thread{
    @Override
    public void run() {
        System.out.println("子线程");
    }
}

public class ThreadTest {
    public static void main(String[] args) {
        Thread thread = new MyThread();
        thread.start();
    }
}

2.实现Runnable接口,实现其run方法

package classFile;

class MyThread implements Runnable{
    @Override
    public void run() {
        System.out.println("子线程");
    }
}

public class ThreadTest {
    public static void main(String[] args) {
        Runnable task = new MyThread();
        Thread thread1 = new Thread(task);
        thread1.start();

    }
}

说明:本质上Thread类也是实现了Runnable接口

 3.通过创建FutureTask的对象来实现(带返回值);

package classFile;


import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;

public class ThreadTest {
    public static void main(String[] args) throws Exception {
        Callable<Integer> callable = new Callable() {
            @Override
            public Integer call() throws Exception {
                System.out.println("子线程要执行的方法");
                return 12;
            }
        };
        FutureTask task = new FutureTask(callable);
        // FutureTask间接实现了Runnable接口
        Thread thread = new Thread(task);
        thread.start();
        // 要获取子线程的返回值
        Integer o = (Integer) task.get(); //主线程等待子线程返回结果
        System.out.println(o);

    }
}

结果:

 4.通过匿名内部类的方式;

package classFile;



public class ThreadTest {
    public static void main(String[] args) throws Exception {
        Thread thread = new Thread(){
            @Override
            public void run() {
                System.out.println("子线程");
            }
        };
        thread.start();

    }
}

当然由于Thread类实现了函数式接口Runnable,所以可以使用lambda表达式来简化操作:

package classFile;



public class ThreadTest {
    public static void main(String[] args) throws Exception {
        Thread thread = new Thread(()-> System.out.println("子线程"));
        thread.start();

    }
}

注意:lambda表达式是java8的新特性,知识体系比较丰富,建议读者单独花时间学习。

5.线程池的方式;

说明:创建线程的方式那么多了,为什么还需要线程池呢?原因之一是:在高并发场景下,不使用线程池情况下,应用程序在每个用户访问时可能都会创建单独的线程,用户访问完毕后,则销毁线程,而创建和销毁线程的开销又是巨大的,且耗内存空间,所能够支持的并发量并不多。而通过线程池,则可以实现线程的复用,节省了大量开销。

代码如下:(使用了ForkJoinPool

package 并发3;


import javax.persistence.criteria.CriteriaBuilder;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;

public class 基于分治思想的线程池的使用 {
    public static void main(String[] args) {
        ForkJoinPool forkJoinPool = new ForkJoinPool(2); //线程池线程的数量
        long start = System.currentTimeMillis();
        forkJoinPool.invoke(new MyTask(1000)); //线程池执行任务
        System.out.println("任务耗时-没优化的并发"+(System.currentTimeMillis()-start));
        // 单线程
        long start2 = System.currentTimeMillis();
        doSum(1000);
        System.out.println("任务耗时--串行"+((System.currentTimeMillis())-start2));
        // 任务拆分下的多线程
        ForkJoinPool forkJoinPool1 = new ForkJoinPool(2);
        long start3 = System.currentTimeMillis();
        forkJoinPool1.invoke(new MyTask1(1,1000));
        System.out.println("优化的并发"+(System.currentTimeMillis()-start3));

    }
    // 单线程递归 1+...+n的和
    public static Integer doSum(int n){
        if (n == 1){
            return 1;
        }
        return doSum(n-1) + n;
    }
}
// 1-5整数和
// 这种拆分方法并发度不高
class MyTask extends RecursiveTask<Integer>{
    private int n;
    @Override
    protected Integer compute() {
        if (n == 1){
            return 1;
        }
        MyTask t1 = new MyTask(n-1);
        t1.fork(); //让一个线程执行任务
        int result = n + t1.join();
        return result;
    }
    public MyTask(int n){
        this.n = n;
    }
}

输出结果:

注释:不同的pc运行结果可能不同,读者可自己测试。 

总结:lambda表达式值得学习,或者说java8的新特性如新时间api,stream流等均值得学习。到此!感谢大佬们的观看。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值