天天看点

多线程(线程的四种创建方式)

1、并发与并行

并行:两个或多个事件在同一时刻发生

并发:两个或多个事件在同一时间段内发生

2、进程与线程

打开浏览器中的百度、淘宝,那么浏览器是一个进程,淘宝和百度是两个线程。

3、线程创建的方式

(1)继承Thread类:

自定义线程:

创建测试类:

main方法也是一个线程被称作主线程,手动创建的线程称为子线程,两个线程中分别书写for循环。

继承Thread类,重写run方法,创建线程的对象并调用start开启线程(注意:调用的是start方法,不是run方法)。这里循环的次数较少是先执行main线程,再去执行另外一个线程,当循环的次数较多时会出现两个线程的交叉执行的现象。

多线程(线程的四种创建方式)

 这里只开辟了一条线程,可以开辟多条线程,主线程和子线程是交替执行的

(2)实现Runnable接口:

实现接口,创建线程:

测试类:

需要创建线程对象,通过线程对象来开启我们的线程,采用的是代理的方式

(3)实现Callable接口

Callable接口:

Callable需要使用FutureTask类帮助执行,FutureTask类结构如下:

多线程(线程的四种创建方式)

 RunnableFuture接口需要实现Future和Runnable两个接口。

Future接口的方法:

判断任务是否完成:isDone()

能够中断任务:cancel()

能够获取任务的执行结果:get()

创建线程:

在创建线程的时候设置了返回值,可以通过get方法获取。

主线程:

在主线程中可以获取到手动创建的线程的返回值。

4、创建线程池

分类:

使用:

多线程(线程的四种创建方式)
多线程(线程的四种创建方式)

好处:

限制线程的个数,不会导致由于线程过多导致系统运行缓慢,甚至崩溃

节省了资源:我们用创建的线程,在使用后都会被销毁,频繁地创建和销毁会造成时间和资源的浪费。线程池是一个能够容纳多个线程的容器,里面的线程可以反复使用。

5、实现接口和继承Thread类比较

(1)接口更适合多个相同的程序代码的线程去共享同一个资源。

可以new多个Thread去调用创建的线程中的run方法,代码的复用增强:

(2)接口可以避免Java中的单继承的局限性

(3)接口代码可以被多个线程共享,代码和线程独立

(4)线程池只能放入实现Runable 或callable 接口的线程,不能直接放入继承Thread的类

扩充:

在java中,每次程序运行至少启动2个线程。一个是main线程,一个是垃圾收集线程。

6、Runnable和Callable接口比较

相同点:

(1)两者都是接口

(2)两者都可用来编写多线程程序

(3)两者都需要调用Thread.start 启动续程

不同点:

(1)实现Callable接口的线程能返回执行结果,而实现Runnable 接口的线程不能返回结果

(2)Callable 接口的call()方法允许抛出异常,而 Runnable 接口的run()方法的不允许批异常

(3)实现Callable 接口的线程可以调用Future.cancel取消执行,而实现runnable 接口的线程不能,不需要控制线程的话没必要用Callable接口

注意点:

Callable 接口支持返回执行结果,此时需要调用FutureTask. get()方法(主线程会被阻塞,不能和main并发执行)实现,此方法会阻塞主线程直到获取“将来’结果;当不调用此方法时,主线程不会阻塞!

 7、线程安全

如果多个线程同时运行同一个实现了Runnable接口的类,程序每次运行的结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的,反之,则是线程不安全的。

每个人都会有一段异常艰难的时光 。 生活的压力 , 工作的失意 , 学业的压力。 爱的惶惶不可终日。 挺过来的 ,人生就会豁然开朗。 挺不过来的 ,时间也会教你 ,怎么与它们握手言和 ,所以不必害怕的。 ——杨绛