java 多线程

java 多线程

java 多线程的几种实现方式

方式 1:通过继承 Thread 类

  • 类 A 继承 Thread 类,重写 run 方法,通过 new 实例化一个 A 类对象,然后对象调用 native 方法 start()启动线程,并且新线程运行 run()方法。
  • Thread 类实现了 runnable 接口,添加了属性变量和实体方法,如:线程名、优先级、分组等,方便实现多线程编程。(这里需要看源码确定描述的正确性和准确性)

public class TestThread{
	class A extends Thread{
		@override
		public void run(){
			
		}
	}
	
	public static void main(String[] args){
		A a = new A();
		a.start();
	}
}

方式二:通过实现接口 Runnable

  • 类 A 通过实现接口 Runnable ,重写 run()方法,通过实例化 Thread ,类 A 作为参数传入,得到实例对象 a, 然后通过 a 调用 native 方法启动线程。
  • Runnable 接口可以实现多继承,解决了类的多继承问题。
public class RunnableTest{
	public class A implements Runnable{
		@override
		public void run(){
			
		}
	}
	
	public static void main(String[] args){
		A a = new A();
		Thread thread = new Thread(a);
		thread.start();
	}
}

方法三:实现 Callable 接口,通过 FutureTask 包装器来创建 Thread 线程

在这里插入图片描述

  • Callable 接口只有一个方法,源码如下:
public interface Callable<V>{
	V call() throws Exception;
}
  • 类 A 实现接口 Callable,重写 call 方法,实例化 类 A 得到对象 a,将 a 作为参数实例化 FutureTask 类得到 futureTask 对象,将 futureTask 对象作为参数实例化 Thread 类得到 thread 对象,使用 thread 调用 native 方法 start()启动线程
public class CallableTest {
	public class A implements Callable<V>{
		public V call() throws Exception{
			return "test success";
		}
	}
	
	public static void main(String[] args){
		A<V> a = new A<V>();
		FutureTask<V> futureTask = new FutureTask<V>(a);
		Thread thread = new Thread(futureTask);
		thread.start();
		futureTask.get();//获取返回值,此处会阻塞等待结果。
	}
}

第四种方法:使用线程池实现多线程

  • 使用 ExecutorService 接口、Callable 接口(或者 Runnable)、Future 接口实现多线程。
使用工厂类 Executors 创建线程池,执行 Callable 任务后,得到一个 Future 对象,通过该对象可以获取返回值。
public class CallableFutureTaskExecutorsTest(){
	
	public class CallableImpl implements Callable<V>(){
		@override
		public <V> call() throws Exception{
			return "success!";
		}
	}
	
	public static void main throws Exception interruptedException(String[] args){
		int taskSize = 5;
		ExecutorService pool = Executors.newFixedThreadPool(taskSize);
		ArrayList<Future> list = new ArrayList<Future>();
		for (int i=0; i<taskSize; i++){
			CallableImpl call = new CallableImpl();
			Future f = pool.submit(call);
			list.add(f);
		}
		
		pool.shutdown();
		for (int i=0; i<taskSize; i++){
			list.get(i).get();
		}
	}
}
使用工厂类 Excutors 创建线程池,执行 Runnable 任务后,实现多线程,代码与上面类似==(Runnable 分为又返回值和无返回值的,这里可能需要更正,且需要后面补充代码)==。

多线程参考文档

多线程实现方式参考1
多线程实现方式参考2

java 线程池

ExecutorService 线程池接口:

  • ExecutorService 是接口是用来设置线程池接口,并执行多线程。ExecutorService 里面有很多静态方法,如下:
    在这里插入图片描述

  • ExecutorService 有两个实现类,ScheduledThreadPoolExecutor 和 ThreadPoolExecutor,Executors 为工厂类,为 ExecutorService 组合了 Executors(类似:人组合了大脑,人可以使用大脑,大脑生命周期和人一样),如下:
    在这里插入图片描述

Executors 工厂类

  • 在 Executors 工厂类中提供了各种创建线程池的方法
    在这里插入图片描述

  • 不建议使用 Executors 工厂类来创建线程池,比如使用Executors.newFixedThreadPool(int)创建线程时,初始化线程池的时候,里面有一个阻塞队列参数 BlockingQueue(ArrayBlockingQueue 数组实现,必须设置大小;LinkedBlockingQueue 链表实现,容量可以选择设置或者不设置,当不设置时,默认最大值为 Interger.MAX_VALUE,没有设置时意味着可以基本等于无限制向队列里面添加任务,这时候就会导致 OOM。

import java.util.*;

public class ExecutorsOutOfMemoryErrorTest{
	public class RunnableImpl implements Runnable{
		@override
		public void run(){
			try {
				System.out.println("success!");
				Thread.sleep(1000000);
			}catch(InterruptedException e){
				e.printStackTrace();
			}
		}
	}
	
	public static void main(String[] args){
		int taskSize = 5;
		ExecutorService pool = Excutors.newFixedThreadPool();
		for (int i=0; i<taskSize; i++){
			RunnableImpl run = new RunnableImpl();
			pool.execute(run);
		}
	}
}
  • 阻塞队列。解决生产者消费者问题,生产者生成放置于队列中,消费者取队列中依次获取,当队列满时,生产者这端线程进入阻塞等待。

ThreadPoolExecutor 线程池类

  • ThreadPoolExecutor 构造函数

ScheduledThreadPoolExecutor 线程池类

线程池参考文档

ExecutorService介绍
ExecutorService 线程池
常见面试题:线程池
ThreadPoolExecutor、ScheduledThreadPoolExecutor及Executors工厂类
Executors创建线程池弊端

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值