码迷,mamicode.com
首页 > 编程语言 > 详细

java多线程---创建线程的几种方式

时间:2019-09-22 22:00:24      阅读:92      评论:0      收藏:0      [点我收藏+]

标签:mit   execution   利用   time   exce   线程池   nts   ace   Fix   

创建线程的几种方式

  在并发编程中,创建线程是我们经常会做的事情,那么一般来说,创建线程有4种方式:

  1、继承Thread类。

  2、实现Runnable接口。

  3、实现Callable接口,结合FutureTask来使用。

  4、利用线程池的方式来实现。

 

继承Thread创建线程

public class ThreadTest1 extends Thread {
    @Override
    public void run() {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("ThreadTest1 is running");
    }

    public static void main(String[] args) throws InterruptedException {
        ThreadTest1 threadTest1=new ThreadTest1();
        threadTest1.start();
        System.out.println("第一次:"+System.currentTimeMillis());
        Thread.sleep(1000);
        threadTest1.run();
        System.out.println("第二次:"+System.currentTimeMillis());
    }
}
执行结果为:

第一次:1569155515336
ThreadTest1 is running
ThreadTest1 is running
第二次:1569155517338

  由上述例子可以看出,调用threadTest1.start()的时候先执行的输出时间然后执行的线程中的输出语句,而调用threadTest1.run()方法先执行的是ThreadTest1中的run()方法后执行主线程中的输出实际的语句,所以可以得出,直接调用run()方法不是启动线程的方式,而是直接调用线程中的run()方法和线程无关,启动线程的方式是调用Thread.start()方法。

实现Runnable接口创建线程

public class ThreadTest2 implements Runnable {
    @Override
    public void run() {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Thread is running");
    }

    public static void main(String[] args) {
        ThreadTest2 threadTest2=new ThreadTest2();
        Thread thread=new Thread(threadTest2);
        thread.start();
        System.out.println(System.currentTimeMillis());
    }
}

  实现接口Runnable来创建线程也是一种实现方式,与继承Thread类创建线程的不同在于,一个是继承、一个是实现接口,由于JAVA不允许多继承,所以在实际项目中实现Runnable接口来创建线程的方式还是用的比较多的。

 

实现Callable接口

 

public class ThreadTest3 implements Callable<Integer> {
    @Override
    public Integer call() throws Exception {
        int i = 0;
        for (; i < 100; i++) {
            System.out.println(Thread.currentThread().getName() + " " + i);
        }
        System.out.println(Thread.currentThread().getName() + " " + i);
        return i;
    }

    public static void main(String[] args) throws InterruptedException {
        ThreadTest3 threadTest3 = new ThreadTest3();
        //很重要,无论多少个线程调用futureTask,futureTask只会执行一次
        FutureTask<Integer> futureTask = new FutureTask<Integer>(threadTest3);
        Thread thread1 = new Thread(futureTask, "aa");
        Thread thread2 = new Thread(futureTask, "bb");
        Thread thread3 = new Thread(futureTask, "cc");
        thread1.start();
        Thread.sleep(3000);
        thread2.start();
        Thread.sleep(3000);
        thread3.start();
        try {
            System.out.println("最终结果为" + futureTask.get());
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

    }
}

 

  实现Callable接口最重要的就是可以得到线程执行的返回值,但是实现Callable接口的类需要配合FutureTask来使用,同时我们注意到上面的例子很重要的一点,就是无论多少个线程来执行futuretask最终只会有一个线程执行,所以这种方法在并发变成中会很安全,不用担心多个线程调用了使得结果不正确。

 

使用线程池来创建线程

public class ThreadMain {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
       ExecutorService executorService= Executors.newFixedThreadPool(3);
        Callable<Integer> callable=new ThreadTest3();
        Future f=executorService.submit(callable);
        System.out.println("最终结果为" + f.get());
        executorService.shutdown();

        ExecutorService executorService2=Executors.newFixedThreadPool(3);
        Thread thread=new ThreadTest1();
        executorService2.execute(thread);
        executorService2.shutdown();
    }
}

  使用线程池来创建线程主要依靠的是Executors中的静态方法来创建线程池,实际上该种方法来创建线程本质还是上面3种方式,只不过在实际运用中使用多线程来执行任务用的比较多。

 

java多线程---创建线程的几种方式

标签:mit   execution   利用   time   exce   线程池   nts   ace   Fix   

原文地址:https://www.cnblogs.com/rhodesis/p/11569178.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!