本季目标
[零基础学JAVA]Java SE应用部分-23.多线程(01)_Runnable
多线程这一个部分,重点掌握以下几点(概念):
·线程与进程的区别
·java中多线程的实现方式及区别
·java线程的同步与死锁
多线程的基本概念(1)
[零基础学JAVA]Java SE应用部分-23.多线程(01)_JAVA_02
DOS开始的:如果一旦出现了病毒,则操作系统就会死掉,因为DOS在同一个时间段上只能有一个程序运行。
Windows:如果出现了病毒操作系统是不是依然可以使用呢?
但是电脑的CPU 有几个?一个?多进程是将CPU的资源进行划分,在同一个时间段上会有多个程序运行,但是在同一个时间点上只能有一个程序运行。
进程与线程的关系?
操作系统可以有多个进程
每个进程上会划分出多个线程
如果进程消失了,则线程也会消失
如果线程消失了,则进程未必会消失。
多线程的基本概念(2)
[零基础学JAVA]Java SE应用部分-23.多线程(01)_JAVA_03
多线程本身还是需要操作系统支持的。也就是说使用多线程会提供资源的利用率。
JAVA线程的实现
[零基础学JAVA]Java SE应用部分-23.多线程(01)_多线程_04
[零基础学JAVA]Java SE应用部分-23.多线程(01)_多线程_05
程序依次执行线程A、线程B、线程C,好像体现不出同一个时间段上有多个程序运行哈~
[零基础学JAVA]Java SE应用部分-23.多线程(01)_JAVA_06
以上代码是通过run方法调用的,没有启动多线程机制。实际上注意一点:各个操作系统都有各自的资源划分,也就是说,如果要想在一个操作系统上实现多线程程序,则肯定不能直接去调用run(类中的方法)启动,而应该告诉操作系统,由操作系统进行分配。
[零基础学JAVA]Java SE应用部分-23.多线程(01)_run()_07
如果想要启动多线程,则肯定调用start()方法,start方法可以调用被子类覆写过的run方法
[零基础学JAVA]Java SE应用部分-23.多线程(01)_JAVA_08
我们现在看下程序能否启动多线程
[零基础学JAVA]Java SE应用部分-23.多线程(01)_JAVA_09
通过start()方法确实调用run方法,此时的程序确实是同时运行着,而且是交替运行,谁抢到了CPU资源,谁就运行。
为什么非要调用start()方法启动呢?
[零基础学JAVA]Java SE应用部分-23.多线程(01)_多线程_10
[零基础学JAVA]Java SE应用部分-23.多线程(01)_多线程_11
JDK中Thread类的定义
[零基础学JAVA]Java SE应用部分-23.多线程(01)_Runnable_12   
其中started是在方法中定义一个boolean变量,判断这个线程是否己被启动,如果没有启动,则执行此段代码,表示线程已经启动,线程加入就绪状态,调用start0这个私有方法,此方法表示要调用操作系统的函数。
[零基础学JAVA]Java SE应用部分-23.多线程(01)_Runnable_13
native是一个关键字
  在JAVA中有种技术:JNI(Java Native  Interface),可以使用JAVA程序调用本机操作系统的函数,以达到某些功能。
如果再次启动一个已经启动的线程,则会如何呢?
[零基础学JAVA]Java SE应用部分-23.多线程(01)_JAVA_14
[零基础学JAVA]Java SE应用部分-23.多线程(01)_Runnable_15
程序会抛出一个IllegalThreadStateException()异常
记住:只要是线程启动一次就OK啦。
以上程序实际上也存在问题?
  如果一个类必须继承Thread类才能实现多线程,则此类肯定就不能再继承其他的类了,即:如果使用Thread会受到单继承的局限,所以一般实现多线程都是实现Runnable接口。
[零基础学JAVA]Java SE应用部分-23.多线程(01)_Runnable_16
在Thread类的构造方法处:
  public Thread(Runnable target) --> 表示只要是Runnable接口的子类对象都可以向里面传递。
[零基础学JAVA]Java SE应用部分-23.多线程(01)_Runnable_17
[零基础学JAVA]Java SE应用部分-23.多线程(01)_JAVA_18
验证下效果,多线程确实起作用了哈~
[零基础学JAVA]Java SE应用部分-23.多线程(01)_Thread_19
结论:不管那种方式实现多线程,最终永远都是通过Thread类启动多线程。
Thread类与Runnable接口(1)
[零基础学JAVA]Java SE应用部分-23.多线程(01)_Thread_20
Thread类也是实现了Runnable接口哈~
[零基础学JAVA]Java SE应用部分-23.多线程(01)_run()_21
[零基础学JAVA]Java SE应用部分-23.多线程(01)_run()_22
Thread类与Runnable接口(2)
[零基础学JAVA]Java SE应用部分-23.多线程(01)_JAVA_23
1、避免单继承局限
2、可以达到多个线程的资源共享
[零基础学JAVA]Java SE应用部分-23.多线程(01)_多线程_24
验证下效果哈~
[零基础学JAVA]Java SE应用部分-23.多线程(01)_Runnable_25
我们发现这个程序有点问题,三个线程各占了10张票,一共卖了30张票,为什么会这样呢?因为private int ticket = 10 ;这个属性,一旦实现了下面的代码:
MyThread mt1 = new MyThread();
MyThread mt2 = new MyThread();
MyThread mt3 = new MyThread();
执行之后就完成实例化操作,mt1、mt2、mt3各自占各自的属性,即各占有10张票,这样就没有达到资源共享。
如果我们要实现资源共享,可以修改以上程序,看下面哈~
[零基础学JAVA]Java SE应用部分-23.多线程(01)_JAVA_26
现在三个对象共卖10张票,达到了资源共享的效果哈~~~
 [零基础学JAVA]Java SE应用部分-23.多线程(01)_多线程_27
如果使用了Runnable接口实现了多线程,则所有的线程对象同时占据同一个Runnable接口的子类对象,则证明多个线程共享资源。
结论:肯定一个类实现Runnable接口实现多线程是最好的。
总结
1、进程与线程的区别
  · 线程是在进程基础上的划分
  · 进程是在操作系统上的划分

2、 使用多线程可以发现在同一个时间段上所有的程序是交替运行的。

3、 多线程的实现有两种方式:
  · 实现Runnable接口
  · 继承Thread类

4、 联系与区别:
  ·  Thread类也是Runnable接口的子类
  · 如果要想启动线程,则必须把自定义的实现了Runnable接口的子类对象放入Thread类中
  ·  Runnable接口可以实现多个资源的共享
  · 绝对要优先使用Runnable接口,避免单继承的局限。
#################################################