Java多线程的四种实现方式

2 篇文章 0 订阅
2 篇文章 0 订阅

    多线程(multithreading),是指从硬件或软件上实现多个线程并发执行的技术。

    一、Java多线程的实现方式主要有四种

    Java多线程的实现方式有:继承Thread类、实现Runnable接口、实现Callable接口通过FutureTask包装器来创建Thread线程、使用ExecutorService和Callable以及Future实现有返回结果的多线程

    1.继承Thread类

       Thread类是Runnable接口的一个实现类,代表线程的一个实例。我们实现多线程的时候,可以通过继承Thread类,执行run()方法实现多线程。

       

       

         从上面这两种输出结果可以看出:start()方法输出的结果不一样,这是因为start()方法中含有run()方法,start()方法会创建一个新的线程进行启动;而run()方法直接启动当前线程

         注意:由于Java的特性,如果自己的类已经继承了其他的类(例如上面的例子中Sync类继承了其他的类,则不能再继承Thread类),就无法再继承Thread类,则该种实现多线程的方式就不能再使用

    2.实现Runnable接口

         如果自己的类已经继承了其他的类,则可以实现一个Runnable接口(由于Java一个类可以实现多个接口,则不存在方式1的问题)。例如:

      

        从上面的实例中可以知道:为了启动SyncThread,首先需要实例化一个Thread对象,然后传入自己的SyncThread实例。事实上,当传入一个Runnable的实现类对象给Thread后,Thread的run()方法会调用Runnable的实现类对象的run()方法,参考JDK源代码。

 3.实现Callable接口通过FutureTask包装器来创建Thread线程

         3.1 Callable接口介绍

               ①java.util.concurrent.Callable是一个泛型接口,只有一个call()方法

               ②call()方法抛出Exception异常,且返回一个指定的泛型类对象

         3.2 Callable接口实现多线程的应用场景

               当父线程想要获取子线程的运行结果

         3.3 使用Callable接口实现多线程的步骤

               ①创建Callable子类的实例化对象

              ②创建FutureTask对象,并将①传入FutureTask对象中【FutureTask类实现了Runnable接口和Future接口】

              ③创建Thread对象,并将②传入Thread对象中

              ④启动线程

          例如:

                  

  4.使用ExecutorService和Callable以及Future实现有返回结果的多线程【线程池的方式】      

         ExecutorService接口和Callable接口以及 Future接口都是属于EXecutor框架

         4.1 Executor框架

               Executor框架是在Java1.5中引入的,它把任务的提交和执行进行解耦,只需要将写好的任务方法交给线程池就行了。例如:

 

           其中:①表示的是初始化包含10个线程的Executor线程池;②表示的是调用线程池中的线程来执行任务

      4.2 可返回值的任务必须实现Callable接口,无返回值的任务必须实现Runnable接口

            执行Callable任务后,可以获取一个Future的对象,在该对象调用get就可以获取当Callable任务返回的Object对象了

            其中:get方法是阻塞的,即:线程无返回结果,get方法会一直等待

            再结合线程池接口ExecutorService就可以实现有返回结果的多线程了。

            例如:

                   

package com.peng.demo.sync;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class SyncThread{
	public static void main(String[] args) throws InterruptedException, ExecutionException {
		System.out.println("程序开始执行");
		Date date = new Date();
		
		//创建含有5个线程的线程池
		ExecutorService executorService = Executors.newFixedThreadPool(10);
		//用来储存返回值结果
		List<Future<Object>> list = new ArrayList<Future<Object>>();
		for(int i = 0; i < 10; i++){
			Callable<Object> callable = new Sync(Integer.toString(i));
			//执行callable任务并返回future对象
			Future<Object> future = executorService.submit(callable);
			list.add(future);
		}
		//关闭线程池
		executorService.shutdown();
		//获取所有任务的运行结果
		for (Future<Object> future : list) {
			System.out.println(future.get().toString());
		}
		Date date2 = new Date();
		long time = date2.getTime() - date.getTime();
		System.out.println("程序结束运行,运行时间为【" + time + "】毫秒");
	}
}

class Sync implements Callable<Object>{
	
	private String taskNumber;
	
	public Sync(String taskNumber) {
		this.taskNumber = taskNumber;
	}

	@Override
	public Object call() throws Exception {
		System.out.println(taskNumber + "任务启动");
		Date tempData1 = new Date();
		Thread.sleep(1000);
		Date tempData2 = new Date();
		long time = tempData2.getTime() - tempData1.getTime();
		System.out.println(taskNumber + "任务终止");
		return taskNumber + "执行的任务时间【" + time +"】毫秒";
	}
}
程序运行结果:
    程序开始执行
    0任务启动
    1任务启动
    2任务启动
    3任务启动
    4任务启动
    5任务启动
    6任务启动
    7任务启动
    8任务启动
    9任务启动
    4任务终止
    3任务终止
    0任务终止
    7任务终止
    5任务终止
    2任务终止
    0执行的任务时间【1000】毫秒
    6任务终止
    1任务终止
    1执行的任务时间【1000】毫秒
    2执行的任务时间【1000】毫秒
    8任务终止
    9任务终止
    3执行的任务时间【1000】毫秒
    4执行的任务时间【1000】毫秒
    5执行的任务时间【1000】毫秒
    6执行的任务时间【1000】毫秒
    7执行的任务时间【1000】毫秒
    8执行的任务时间【1000】毫秒
    9执行的任务时间【1000】毫秒
    程序结束运行,运行时间为【1005】毫秒

 

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值