前言
单线程的程序只有一个顺序执行流,多线程的程序则可以包括多个顺序执行流,多个顺序流之间互不干扰
当一个程序运行时,内部可能包含了多个顺序执行流,每个执行流就是一个线程
一个进程可以同时并发处理多个线程,这些线程相互独立,其中存在一个主线程,多个线程并发轮转执行
同一父进程的多个线程之间共享父进程的全部资源,进程的共有数据,因此会造成数据安全问题,需实现线程间的同步
进程与线程
先进一般配置的电脑的进程大都是并发执行(一个电脑同时并发(时间片轮转)处理多个进程)---------------多进程
多线程则扩展了多进程的概念,使得同一个进程可以同时并发处理多个任务------------------------------------------多线程
当进程被初始化后,主线程就被创建了,对大多应用程序而言,通常要求有一个主线程,但也可以在该进程内创建多条顺序执行流,这些顺序执行流就是县城,每个线程相互独立
多线程存在与一个应用程序中,让一个应用程序中可以由多个执行部分同时并发执行
java如何支持多线程的?
java用Thread类抽象了线程,每一个Thread对象就是一个线程
Thread源码
public class Thread implements Runnable {
private volatile String name;
private int priority;
private Thread threadQ;
private long eetop;
public synchronized void start() {}
@Override//重写Runnable的run()方法
public void run() {
if (target != null) {
target.run();
}
}
@Deprecated//已过时的stop方法
public final void stop() {}
private void exit() {}
public void interrupt() {}
@Deprecated//已过时的destroy方法
public void destroy() {
throw new NoSuchMethodError();
}
@Deprecated//已过时的suspend方法
public final void suspend() {
checkAccess();
suspend0();
}
@Deprecated//已过时的resume方法
public final void resume() {
checkAccess();
resume0();
}
public Thread(Runnable target, String name) {
init(null, target, name, 0);
}
}
Runnable接口的源码
@FunctionalInterface public interface Runnable {
public abstract void run(); }
我们注意到Runnable接口里就只有一个run()方法,是一个函数式接口,只有一个抽象方法,而且Thread类实现Runnable接口
默认运行程序时,会先创建一个jvm的虚拟机进程,默认有一个主线程,主线程的线程执行体是由main()决定的,main()方法的方法体代表主线程的线程执行体,通过Thread类为该进程创建多个线程,run()的方法体代表其他线程的线程执行体,多个线程并发执行
在默认情况下,jvm虚拟机进程下,主线程的名字卖弄,用户启动的多个线程的名字以此为Thread-0,Thread-1...............
怎么创建线程呢?线程有帮助我们完成了什么任务呢?
继承Thread类创建线程类
(1)创建Thread的子类,重写run方法(run()是线程执行体,是一个顺序流,是该线程要完成的任务),继承了Thread方法
(2)创建子类的实例,一个线程对象被创建,一个主进程中就会存在多线程了,存在多线程的并发执行,顺序执行流是run()
(3)调用线程对象的start()方法来启动线程
Thread创建的多个线程,多个线程之间只能共享进程的公共数据,不能共享线程的局部变量
实现Runnable接口创建线程类
(1)定义Runnable接口的实现类,重写run()方法,(run()是线程执行体,是一个顺序流,是该线程要完成的任务)
(2)创建实现类的实例,将此实例作为Thread的target来创建Thread对象,Thread为线程对象
(3)调用线程对象的start()方法来启动线程
Runnable创建的多个线程,多个线程之间即能共享进程的公共数据,又能共享线程的局部变量,因为多个线程之间共享线程的target
使用Callable接口和Future接口来创建线程
(1)定义Callable接口的实现类,实现call()方法,call()作为线程执行体,
(2)创建实现类的实例
(3)使用FutureTask类来包装Callable的实例,
(4)使用FutureTask对象作为Thread对象的target
(5)调用线程对象的start()方法来启动线程
Callable接口----函数式接口
@FunctionalInterface public interface Callable<V> {
V call() throws Exception; }
Future接口
public interface Future<V> {
boolean cancel(boolean mayInterruptIfRunning);
boolean isCancelled();
V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException; }
创建线程的三种方式的总结
(1)线程类实现Runnable和Callable接口,创建线程对象,可以使得多个线程之间共享同一个target对象,适合多个i相同线程来处理同一份资源
(2)线程类还可以继承其他类