Java创建多线程的四种方式Java创建多线程的四种方式
目录
方式一:通过继承Thread类的方式
方式二:通过实现Runnable接口的方式
方式三:通过实现Callable接口的方式
方式四:通过线程池的方式
对于start()方法的解释
方式一:通过继承Thread类的方式
步骤:
1.创建类继承Thread类
2.重写Thread类中的run()方法
3.创建子类的实例对象
4.调用子类实例对象的start()方法
例:创建一个线程实现输出0~100
package test1; //创建继承Thread类的子类 public class ThreadTest1 extends Thread{ //重写该子类的run()方法 public void run() { for(int i=1;i<=100;i++) { System.out.println("数"+i); } } } package test1; public class ThreadTest { //主线程 public static void main(String []args) { //创建子类的实例化对象 ThreadTest1 threadTest1=new ThreadTest1(); //调用子类实例化对象的start()方法 threadTest1.start(); } }
方式二:通过实现Runnable接口的方式
步骤:
1.创建Runnable接口的实现类
2.重写该实现类的run()方法
3.创建该实现类的实例化对象
4.以该实例化对象为参数创建Thread类的实例化对象
5.调用Thread类的实例化对象的start()方法
例:创建一个线程实现输出0~100
package test1; //创建实现Runnabl接口的子类 public class ThreadTest1 implements Runnable{ //重写该实现类的run()方法 public void run() { for(int i=1;i<=100;i++) { System.out.println("数"+i); } } } package test1; public class ThreadTest { //主线程 public static void main(String []args) { //创建实现类的实例化对象 ThreadTest1 threadTest1=new ThreadTest1(); //以实现类的实例化对象为参数创建Thread类的实例化对象 Thread theadThread=new Thread(threadTest1); //调用Thread类的实例化对象的start()方法 theadThread.start(); } }
方式三:通过实现Callable接口的方式
步骤:
1.创建实现Callable接口的实现类
2.重写该实现类的call方法
3.创建该实现类的实例化对象
4.以Callable实现类的实例化对象为参数创建FutureTask类的实例化对象
5.以FutureTask类的实例化对象为参数创建Thread类的实例化对象
6.调用Thread类的实例化对象的start()方法
7.call方法有返回值,如果需要获取返回值则调用FutureTask类的实例化对象的get()方法
例:创建一个线程实现输出0~100,并返回1到100之和
package test1; import java.util.concurrent.Callable; //创建实现Callable接口的子类 public class ThreadTest1 implements Callable{ //重写该实现类的call()方法 @Override public Object call() throws Exception { Integer sum=0; for (int i=1;i<=100;i++) { System.out.println("数"+i); sum+=i; } return sum; } } package test1; import java.util.concurrent.ExecutionException;import java.util.concurrent.FutureTask; public class ThreadTest { //主线程 public static void main(String []args) { //创建实现类的实例化对象 ThreadTest1 threadTest1=new ThreadTest1(); //以实现类的实例化对象为参数创建FutureTask类的实例化对象 FutureTask futureTask=new FutureTask(threadTest1); //以FutureTask类的实例化对象为参数创建Thread类的实例化对象 Thread theadThread=new Thread(futureTask); //调用Thread类的实例化对象的start()方法 theadThread.start(); //调用FutureTask类的实例化对象的get()方法 try { Integer sumInteger=(Integer) futureTask.get(); int sum=sumInteger; System.out.println(sum); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ExecutionException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
方式四:通过线程池的方式
步骤:
1.创建线程池
2.创建Thread类或实现了Runnable或者Callable的类(重写了run()/call()方法)的实例化对象
3.调用线程池中的某个线程执行任务
4.关闭线程池
例:通过线程池使用一个线程输出1-100的整数
package test1; import java.util.concurrent.Callable; //创建实现Callable接口的子类 public class ThreadTest1 implements Callable{ //重写该实现类的call()方法 @Override public Object call() throws Exception { Integer sum=0; for (int i=1;i<=100;i++) { System.out.println("数"+i); sum+=i; } return sum; } } package test1; import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Future; public class ThreadTest { //主线程 public static void main(String []args) { //创建有10个线程的线程池 ExecutorService executorService=Executors.newFixedThreadPool(10); /*上行代码中ExecutorService为真正的线程池接口,Executors是线程池工具类 * newFixedThreadPool(int n)是Executors工具类的一个静态方法,用来获取 * 具有n个线程的线程池 */ //创建实现了Callable接口的实现类的实例化对象 ThreadTest1 test1=new ThreadTest1(); //调用线程池中的某个线程执行任务 Future sum=executorService.submit(test1); /*如果是Thread的子类或者是实现了Runnable接口的类使用void execute(Runnable command) 方法 */ //关闭线程池 executorService.shutdown(); } }
对于start()方法的解释
start()有两个作用:
1.启动一个线程
2.调用该线程的run()方法
对于run()方法的解释:
通过上面的创建多线程示例,我们发现如果是实现Runnable和Callable接口的方式,我们的线程执行的代码(也就是重写的run()和call())并不是我们通过具体实现类来调用的,而是通过一个Thread类的实例化对象调用start()后系统调用的。这是因为我们通过Thread类的实例化对象调用start()后其会调用run()而Thread的run()的源码如下:
/* What will be run. */
private Runnable target;
------
@Override
public void run() {
if (target != null) {
target.run();
}
}
也就是说,如果Thread类的对象在示例化时参数传入了一个实现Runnable接口的对象,则会调用参数对象的run()方法,所以能调用我们实现类的run()和call()。
————————————————
版权声明:本文为CSDN博主「COWARD_LOVE1」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/m0_71987537/article/details/125276364