Java多线程—创建多线程的两种方式

JDK新增的创建多线程的两种方式——Callable和线程池

Callable实现多线程

重写call方法
可以向线程传递数据,可以向上报一个异常
需要借助Future接口(FutureTask类)






1、创建并实现一个Callable的实现类MyCallable
2、实现call方法,将此线程需要执行的操作声明在call()中,可带有返回值
3、创建Callable接口实现类的对象myCallable
4、将Callable接口实现类的对象传递到FutureTask构造器中,创建FutureTask的对象
5、将FutureTask的对象作为参数传递到Thread类的构造器中,创建线程对象并调用start()
6、可以去获取Callable中call()的返回值——futureTask.get()

public class CallableTest {
    public static void main(String[] args) {
        MyCallable myCallable=new MyCallable();
        FutureTask futureTask=new FutureTask(myCallable);

        new Thread(futureTask).start();
        try {
            int result=(Integer) futureTask.get();
            System.out.println(result);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}

class MyCallable implements Callable {
    @Override
    public Object call() throws Exception{
        int sum=0;
        for(int i=0;i<=100;i++){
            System.out.println(i);
            sum+=i;
        }
        return sum;
    }
}

> 理解:Callable接口比Runnable更强大 1、call()可以有返回值 2、call()可以抛出异常,被外面的操作捕获,获取异常的信息 3、Callable支持泛型

线程池实现多线程

public class ThreadPoolTest {
    public static void main(String[] args) {
        ExecutorService service= Executors.newFixedThreadPool(10);

        //设置线程池属性,特殊点
        ThreadPoolExecutor serviceExecutor = (ThreadPoolExecutor) service;  //因为前面service是接口多态的引用,
                                                                            // 不能调用实现类的属性变量和getset方法
//        ThreadPoolExecutor serviceExecutor2= (ThreadPoolExecutor) Executors.newFixedThreadPool(10);
//        serviceExecutor2.execute(new MyRun1());     //ps:这也意味着上述接口的实现类也可以直接使用execute()

        //serviceExecutor.setMaximumPoolSize(15); //设置池中最大线程数
        //serviceExecutor.setKeepAliveTime(10000);  //设置线程没任务时最多保持多久之后终止

        service.execute(new MyRun1());  //从线程池中拿到一个线程并执行,使用Runnable接口
        service.execute(new MyRun2());
//        service.submit(Callable callable);    //使用Callable接口

        service.shutdown();     //关闭线程池
    }
}

使用线程池的好处:
-提高相应速度(减少创建新线程的时间)
-降低资源消耗(重复利用线程池中的线程,不需要每次都创建)
-便于线程管理
.corePoolSize:核心池的大小
.maximumPoolSize:最大线程数
.keepAliveTime:线程没有任务是最多保持多长时间后会终止

posted @ 2022-05-04 18:43  JayerListen  阅读(327)  评论(0编辑  收藏  举报