为了账号安全,请及时绑定邮箱和手机立即绑定

2021.03.23面试总结(多线程的创建)

标签:
Java 面试

多线程有几种实现方法?分别是什么?

1.继承Thread类,重写run()方法,代码如下
步骤:
   (1)继承Tread类,重写run()方法(线程要实现的东西)
    (2)   new一个子类实例
   (3) 执行start方法
public class ExtendThreadTest extends Thread {
    @Override
    public void run(){
        System.out.println("线程任务进行。。。");
    }

    public static void main(String[] args){
        System.out.println("new 实例。。。");
        ExtendThreadTest threadTest = new ExtendThreadTest();
        System.out.println("启动线程");
        threadTest.start();
    }
}
2.实现Runable接口,重写run()方法,把此类作为target传入创建的Thread类中(这种方法的好处,就是java不支持多继承,但是支持多实现,当一个类已经继承其他类的时候,可以用这个方法),代码如下:
步骤:
         (1)实现Runnable方法,重写run()(线程中要实现的东西)
         (2)new Thread实例,传对象(new 实现类)进去
         (3)执行start方法
public class ImplRunnableTest implements Runnable {
    @Override
    public void run() {
        System.out.println("线程处理。。。");
    }

    public static void main(String[] args){
        System.out.println("new 实例,传参");
        ImplRunnableTest runnableTest = new ImplRunnableTest();
        Thread thread = new Thread(runnableTest);
        System.out.println("执行start方法");
        thread.start();
    }
}
3.实现Callable,重写call()方法,然后用FutureTask包装,作为target传入Thread实例中,这样可以处理线程中需要返回的数,用FutureTask中get()获取返回值,代码如下:
步骤:
    1.实现Callable类,重写call()方法
    2.new实现类的实例
    3.用FutureTask类包装实现类
    4.将FutureTask 对象作为target 传给Tread
    5.调用start()启动线程
   其中,可以改用FutureTask类中get()方法获取call方法中的返回值
public class ImplCallableTest2 implements Callable<Integer> {
    @Override
    public Integer call() throws Exception {
        Integer i = 1;
        return i;
    }

    public static void main(String[] args){
        System.out.println("new Callable实现类实例");
        ImplCallableTest2 callableTest2 = new ImplCallableTest2();
        System.out.println("用FutureTask类包装实现类");
        FutureTask<Integer> futureTask = new FutureTask<>(callableTest2);
        System.out.println("把futureTask对象作为target传入Tread");
        Thread thread = new Thread(futureTask);
        System.out.println("启动线程");
        thread.start();
        System.out.println("用get()方法获取返回值");
        try {
            System.out.println(futureTask.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}
4.利用线程池创建
(Executors类:提供了一系列工厂方法用于创建线程池,返回的线程池都实现了ExecutorService接口。
但是不推荐使用这种方法,而是通过ThreadPoolExecutor的方式,自己设置一些参数,明确运行规则
,避免一些其他问题导致OOM,阿里建议多线程采用线程池的方法,减少线程上下文切换所带来的的损耗,并且帮忙管理线程,避免不必要的问题)
public class TreadFactoryTest {

    public static void main(String[] args){
       //核心线程数
        int corePoolSize = 2;
        //最大线程数
        int maximumPoolSize = 4;
        //最大空闲时间
        long keepAliveTime = 10;
        //最大空闲时间单位
        TimeUnit timeUnit = TimeUnit.SECONDS;
        //阻塞队列
        BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(2);
        //线程工厂
        ThreadFactory threadFactory = new NameTreadFactory();
        //拒绝策略
        RejectedExecutionHandler handler = new RejectPolicy();
        ThreadPoolExecutor executor = null;
        try {
            //推荐使用这种方式创建线程池
            executor = new ThreadPoolExecutor(corePoolSize,maximumPoolSize,keepAliveTime,timeUnit,
                                               workQueue,threadFactory,handler);

            //预启动所有核心线程,提升效率
            executor.prestartAllCoreThreads();
            //任务数
            int count = 10;
            for (int i = 1; i <=count; i++) {
                RunnableTask task = new RunnableTask(String.valueOf(i));
                executor.submit(task);

            }
        } finally {
            assert executor != null;
            executor.shutdown();

        }


    }

    static class NameTreadFactory implements ThreadFactory {
        //线程Id
        private final AtomicInteger threadId = new AtomicInteger(1);
        @Override
        public Thread newThread(Runnable r) {
            Thread thread = new Thread(r,"线程-"+threadId.getAndIncrement());
            System.out.println(thread.getName()+"已经被创建");
            return thread;
        }
    }

    public static class RejectPolicy implements RejectedExecutionHandler {
        @Override
        public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
            doLog(r,executor);
        }

        private void doLog(Runnable r, ThreadPoolExecutor executor){
            System.err.println(r.toString()+" rejected");
        }

    }

     static class RunnableTask implements Runnable{

        private String name;

        public RunnableTask(String name){
            this.name=name;
        }
        @Override
        public void run() {
            System.out.println(this.toString()+" is running!");
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

         @Override
         public String toString() {
             return "RunnableTask{" +
                     "name='" + name + '\'' +
                     '}';
         }
     }
}

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
JAVA开发工程师
手记
粉丝
0
获赞与收藏
3

关注作者,订阅最新文章

阅读免费教程

  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消