

多线程的四种实现方式
source link: http://www.cnblogs.com/xpybsh/p/12818796.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

JDK5.0之后Java多线程的实现方式变成了四种,下面来简单的列举一下,如果需要更深入的了解,强烈建议阅读一下源码。
一、继承Thread类重写run()方法:
1. 创建一个继承于Thread类的子类
2. 重写Thread类的run() --> 将此线程执行的操作声明在run()中
3. 创建Thread类的子类的对象
4. 通过此对象调用start()
1 // 1、 创建一个继承于Thread类的子类 2 class Test1 extends Thread { 3 4 // 2、 重写Thread类的run() 5 @Override 6 public void run() { 7 //Thread.currentThread().getName():获取当前线程的名字 8 System.out.println("线程需要执行的代码" + "->" 9 + Thread.currentThread().getName()); 10 } 11 12 } 13 14 public class ThreadTest1 { 15 public static void main(String[] args) { 16 // 3、 创建Thread类的子类的对象 17 Test1 test1 = new Test1(); 18 19 //多线程当然可以创建多个对象来开启多个线程 20 Test1 test2 = new Test1(); 21 22 // 4、通过此对象调用start()方法启动线程 23 //start()方法的作用:1)启动当前线程 2)调用当前线程的run()方法 24 test1.start(); 25 test2.start(); 26 } 27 }
顺便插一句并不是test1先调用了start()方法就一定先比test2先执行,不清楚的小伙伴建议先了解一下多线程的概念,这里主要是对实现多线程的几种方式简单总结,概念不再赘述。
二、实现Runnable接口:
1. 创建一个实现Runnable接口的类
2. 实现Runnable中的run()方法
3. 创建实现类的对象
4. 将此对象作为参数传递到Thread类的构造器中,创建Thread类的对象
5. 通过Thread类的对象调用start()
1 //1. 创建一个实现Runnable接口的类 2 class Test2 implements Runnable { 3 // 2. 实现Runnable中的run()方法 4 @Override 5 public void run() { 6 System.out.println("线程需要执行的代码" + "->" 7 + Thread.currentThread().getName()); 8 } 9 } 10 11 public class ThreadTest2 { 12 public static void main(String[] args) { 13 // 3. 创建实现类的对象 14 Test2 test = new Test2(); 15 // 4. 将此对象作为参数传递到Thread类的构造器中,创建Thread类的对象 16 Thread t1 = new Thread(test); 17 Thread t2 = new Thread(test); 18 // 5. 通过Thread类的对象调用start() 19 t1.start(); 20 t2.start(); 21 22 } 23 }
这种实现的方式没有类的单继承性的局限性更适合处理多个线程有共享数据的情况。
三、实现Callable接口
1.创建Callable的实现类
2.实现call方法,将此线程需要执行的操作声明在call()中
3.创建Callable接口实现类的对象
4.将此Callable接口实现类的对象作为传递到FutureTask构造器中,创建FutureTask的对象
5.将FutureTask的对象作为参数传递到Thread类的构造器中,创建Thread对象,并调用start()
6.获取Callable中call方法的返回值
1 import java.util.concurrent.Callable; 2 import java.util.concurrent.ExecutionException; 3 import java.util.concurrent.FutureTask; 4 5 //1.创建Callable的实现类 6 class Test3 implements Callable<Object>{ 7 //2.实现call方法,将此线程需要执行的操作声明在call()中 8 @Override 9 public Object call() throws Exception { 10 int sum = 0; 11 for (int i = 1; i <= 100; i++) { 12 if(i % 2 == 0){ 13 System.out.println(i); 14 sum += i; 15 } 16 } 17 return sum; 18 //如果不需要方法返回值 19 //return null; 20 } 21 } 22 23 24 public class ThreadTest3 { 25 public static void main(String[] args) { 26 //3.创建Callable接口实现类的对象 27 Test3 numThread = new Test3(); 28 //4.将此Callable接口实现类的对象作为传递到FutureTask构造器中,创建FutureTask的对象 29 FutureTask futureTask = new FutureTask(numThread); 30 //5.将FutureTask的对象作为参数传递到Thread类的构造器中,创建Thread对象,并调用start() 31 new Thread(futureTask).start();//用了匿名内部类 /*可以和上面一样写成(相当于): Thread thread = new Thread(futureTask); thread.start(); */ 32 33 try { 34 //6.获取Callable中call方法的返回值 35 //get()返回值即为FutureTask构造器参数Callable实现类重写的call()的返回值。 36 Object sum = futureTask.get(); 37 System.out.println("总和为:" + sum); 38 } catch (InterruptedException e) { 39 e.printStackTrace(); 40 } catch (ExecutionException e) { 41 e.printStackTrace(); 42 } 43 } 44 45 }
这种创建线程的方式更加的麻烦,但是人家相比较实现Runnable接口的方式更强大
相比实现Runnable接口的好处;
1. call()可以有返回值
2. call()可以抛出异常,被外面的操作捕获,获取异常的信息
3. Callable支持泛型
四、线程池
1. 提供指定线程数量的线程池
2.执行指定的线程的操作。需要提供实现Runnable接口或Callable接口实现类的对象
3.关闭连接池
1 import java.util.concurrent.ExecutorService; 2 import java.util.concurrent.Executors; 3 4 /** 5 * 这里可以用实现Runnable的方式 也可以用实现Callable的方式 6 * 7 */ 8 class Test4 implements Runnable { 9 @Override 10 public void run() { 11 System.out.println("代码"); 12 } 13 } 14 15 public class ThreadTest4 { 16 public static void main(String[] args) { 17 // 1. 提供指定线程数量的线程池 这里设置为10 18 ExecutorService service = Executors.newFixedThreadPool(10); 19 20 // 2.执行指定的线程的操作。需要提供实现Runnable接口或Callable接口实现类的对象 21 service.execute(new Test4());// 适合适用于Runnable 22 // service.submit(Callable callable);//适合使用于Callable 23 24 // 3.关闭连接池 25 service.shutdown(); 26 } 27 28 }
这种方式的好处:
1.提高响应速度(减少了创建新线程的时间)
2.降低资源消耗(重复利用线程池中线程,不需要每次都创建)
3.便于线程管理
以上简单列举了创建线程的四种方式,有不少东西没有写;尤其是第四种,设置线程池属性等都没有演示。对于还在学习基础的小伙伴来说,前两种需要先重点掌握,后面两种可以先了解一下,等有一些多线程基础之后再进行后续学习。
Recommend
-
50
区块链自诞生之日起,就伴随着不少反驳的声音。新鲜事物便是如此,在有人的眼里它价值千金,仓箱可期,有人则认为它分文不值,将其视如草芥。但在越来越多的案例看来,区块链确实能成功运用于譬如农业科技、电商、医疗、甚至是艺术品等收...
-
34
一、如下方式存在的问题 new Thread() { @Override public void run() { // 业务逻辑 } }.star...
-
19
在之前的文章中我们知道了线程池各个参数的含义,其中有个参数 handler 我们说了是拒绝策略,具体关于...
-
6
Android多线程的四种方式 – Android开发中文站当我们启动一个App的时候,Android系统会启动一个Linux Process,该Process包含一个Thread,称为UI Thread或Main Thread。通常一个应用的所有组件都运行在这一个Process中,当然,你可以通过修改四大组件在Manifest...
-
4
java自带的四种线程池 java预定义的哪四种线程池? newSingleThreadExexcutor...
-
7
线程创建的几种方式 在并发编程中,最基本的就是创建线程了,那么一般的创建姿势是怎样的,又都有些什么区别 一般来讲线程创建有四种方式: 继承Thread 实现Runnable接口
-
9
Java 线程池四种拒绝策略 jdk1.5版本新增了 JUC 并发包,其...
-
7
浏览器中实现可视化的四种方式 作者:叫苏珊的_ikun 2022-09-26 08:36:39 在 Web 上,图形通常是通过浏览器绘制的。现代浏览器是一 个复杂的系统,其中负责绘制图形的部分是渲染引擎。渲染引擎绘制图形的方式,大...
-
5
Java...
-
9
一、使用原生js实现拖拽 点击打开视频讲解更加详细 <html lang="en"> <...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK