Java多线程实现方式

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/liuzhixiong_521/article/details/79964712

实现方式

Java多线程共有四种不同的实现方式:分别为继承Thread类、实现Runnable接口,实现Callable接口并通过FutureTask包装器创建线程,使用ExecutorService、Callable、Future实现多线程。

继承Thread类实现多线程

Thread类本质上实现了Runnable接口,代表一个线程的实例。启动线程的唯一方法是调用类的start方法。start方法是一个native方法,它将启动一个新线程,并执行run方法。

以这种方式实现多线程较为简单:首先定义自己的类,然后自己的类继承Thread类,并重写run()方法,调用start方法就可以启动一个新线程并执行run方法。示例如下:

public class ThreadDemo extends Thread{
	public void run(){
		System.out.println("ThreadDemo start..");
	}

	public static void main(String[] args) {
		ThreadDemo td = new ThreadDemo();
		td.start();
	}
}

实现Runnable接口实现多线程。示例如下:

public class RunnableDemo implements Runnable{
	@Override
	public void run() {
		System.out.println("RunnableDemo start..");
	}

	public static void main(String[] args) {
		RunnableDemo rd = new RunnableDemo();
		Thread t = new Thread(rd);
		t.start();
	}
}

实现Callable接口并通过FutureTask包装器创建线程。示例如下:

public class CallableDemo{
	public static void main(String[] args) throws InterruptedException, ExecutionException {
		Callable<Integer> call = new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                System.out.println("callable thread start..");
                Thread.sleep(2000);
                return 1;
            }
        };

        FutureTask<Integer> task = new FutureTask<>(call);
        Thread t =  new Thread(task);
        t.start();
   
        System.out.println("do other thing..");
        System.out.println("callable res=" + task.get());
	}
}

使用ExecutorService、Callable、Future实现多线程。示例如下:

public class ExecutorServiceDemo {
	public static void main(String[] args) throws InterruptedException, ExecutionException {
		System.out.println("main start..");
		int taskSize = 5;

		ExecutorService pool = Executors.newFixedThreadPool(taskSize);
		List<Future<Integer>> list = new ArrayList<Future<Integer>>();
		for (int i = 0; i < taskSize; i++) {
			Callable<Integer> c = new MyCallable<Integer>(i + " ");
			Future<Integer> f = pool.submit(c);
			list.add(f);
		}

		pool.shutdown();

		for (Future<Integer> f : list) {
			System.out.println("threads res=" + f.get());
		}
	}
}

class MyCallable<Integer> implements Callable<Integer> {
	private String taskNum;

	MyCallable(String taskNum) {
		this.taskNum = taskNum;
	}

	public Integer call() throws Exception {
		System.out.println("---" + taskNum + " thread start");
		Date dateStart = new Date();
		Thread.sleep(1000);
		Date dateEnd = new Date();
		long time = dateEnd.getTime() - dateStart.getTime();
		return (Integer) (taskNum + " end require[" + time + "ms]");
	}
}

不同实现方式的差异

  • 如果自己定义的类已经继承了其他类,由于java是单根继承,故只能通过实现接口实现多线程。
  • 继承Thread类和实现Runnable接口实现多线程,没有返回值;实现Callable接口和利用ExecutorService实现多线程可以有返回值,并封装与FutureTask和Future中,值得注意的是,获取返回值的get方法,是阻塞方法,即必须等到线程执行结束才能得到返回值。
  • 继承Thread类和实现Runnable接口实现多线程,不能抛出异常;实现Callable接口和利用ExecutorService
    实现多线程,可以抛出异常。

没有更多推荐了,返回首页

私密
私密原因:
请选择设置私密原因
  • 广告
  • 抄袭
  • 版权
  • 政治
  • 色情
  • 无意义
  • 其他
其他原因:
120
出错啦
系统繁忙,请稍后再试