Java基础知识总结(13)——线程

什么是线程:

    进程是指可执行程序并存放在计算机存储器的一个指令序列,它是一个动态执行的过程

    我们打开Windows任务管理器

    看到进程选项卡,比如qq和记事本   

    有的软件对应一个进程,有的软件对应多个进程,比如杀毒软件或者数据库软件

    比较大的软件是多个进程组成的

    

    早期的操作系统都是单任务的操作系统,也就是我们看到的QQ或者音乐播放器,只能一个运行。一个运行结束才能进行下一个程序的运行,必须先听歌曲这歌听完了才能回复好友问题。

    现在操作系统都是多任务操作系统,可以多个程序同时运行。

    

    线程:线程是比进程还要小的运行单位,一个进程包含多个线程


    其实就是一个进程可以包含多个线程,比如说一个程序,由很多行代码组成,那么这有些代码就可以分成很多块,放到不同的线程当中去分别执行,所以我们认为线程可以看做一个子程序。

    程序的运行是靠CPU来处理,那如果只有一个CPU的情况下怎么能保证这些程序都能同时运行?

    我们可以想象成把CPU的执行时间分成很多小块,每一小块的时间都是固定的,我们可以把这一个小块叫做时间片,时间片的时间可以非常短,比如说1ms。

    如果我们有音乐播放器,代码编辑器,QQ三个软件同时运行,那么他们三个怎么获取CPU的执行时间呢?

    这个其实是随机的,我们可以这么考虑,我们音乐播放器运行1ms然后就会把CPU的使用权转给代码编辑器,代码编辑器运行1ms又将使用权转给QQ,那么这些程序就轮流的在很短的时间使用我们的CPU,对CPU来讲这些软件其实是轮流运行的。但是它运行的时间间隔非常的短,所以我们使用者是感觉不到它的变化的。所以我们就能认为这些软件都是同时运行的。

    这个就是时间片的轮转,是通过对CPU时间的轮转来达到同时运行的效果。



线程的创建:

    有两种方式

    1 创建一个Thread类,或者一个Thread子类的对象

    2 创建一个实现Runnable接口的类的对象

    

Thread是一个线程类,位于java.lang包下



Thread类的常用方法


第一个最重要的方法run,不同功能线程之间他们之间的区别就在于run方法中的代码是不相同的,我们可以把run方法中的代码叫做线程体的代码

join方法:字面上是加入,其实是抢占资源


Runnable接口

只有一个方法run();

Runnable是Java中用以实现线程的接口

任何实现线程功能的类都必须实现该接口


Thread定义形式



创建自定义线程


创建并启动线程



创建线程:

    1.通过继承Thread类方式创建线程,重写run()方法

    

注意启动线程不是run方法,启动线程执行的时候还是run方法里的代码

一个线程只能启动一次



当前其实是由两个线程在运行的,另一个是主方法本身他就是一个线程,或者说主线程

当前其实是主线程和mt两个线程在运行

 


发现和以前的普通方法不同,以前是从上往下一次执行

因为这个线程是随机的,这个线程什么时候获得CPU使用权是不好判断的

后面如果多写代码包含循环的时候就更明显了,就是随机的


还有一点线程是不能多次启动的,只能调用一次start()方法



抛出了异常




我们看下运行情况


先是线程1运行10次,再是线程2运行10次


在运行一次发现线程2运行,再是线程1运行

再来一次


这次完全混乱了


整个运行都是随机的,线程想要获得CPU使用权其实是随机的


Runnable接口方式创建线程

为什么要实现Runnable接口?

1.Java不支持多继承,如果你的Class类继承了一个类,再去继承Thread类是不可以的。接口可以实现多个接口

2.不打算重写Thread类的其他方法,如果继承这个类就会继承Thread类所有方法,对线程来说只要重写run()方法就可以了



注意和thread类的区别,要三步


注意如果是成员变量就会随机了

因为这个代码可以被多个线程共享,多个现场是Thread类实例

多个线程共享一个资源

我们的i相当是一个资源我们的两个线程共享资源


线程的状态:

1 新建(New)

2 可运行(Runable)

3 正在运行(Running)

4 阻塞(Blocked)

5 终止(Dead)


线程的生命周期:

就是5个状态的转换过程


如上图,不过stop()方法不建议使用


sleep()方法

它是Thread类方法


作用:在指定的毫秒数内让正在执行的线程休眠(暂停执行)


不过一般需要捕获异常,因为会打断之类的异常


我们可以用来计时,和定期刷新数据


这样会交替运行



jion方法

Thread类方法:

    

作用:等待调用该方法的线程结束后才能执行



我们发现主线程永远是最后运行结束的



这样线程会有先后顺序执行

jion()方法抢占资源


作用:等待该线程终止的最长时间为millis毫秒


线程的优先级:

    Java为线程提供了10个优先级

    优先级可以用整数1-10表示,超出范围会抛异常

    主线程默认优先级为5

    数字越大,优先级越高

优先级常量:

MAX_PRIORITY:线程的最高优先级10

MIN_PRIORITY:线程的最低优先级1

NORM_PRIORITY:线程的默认优先级5

优先级相关方法:



我们发现是5



优先级也是有随机性的

不能完全保证优先级高的一定先执行


多线程的运行问题:

    各个线程是通过竞争CPU时间而获得运行机会的

    各线程什么时候得到CPU时间,占用多久,是不可预测的

    一个正在运行着的线程在什么地方被暂停是不确定的

    

线程同步:

    我们需要将对象进行锁定

    锁定关键字synchronized实现

    同步关键字

    

    关键字用在:成员方法  静态方法 语句块

    

执行期间其他代码不允许打断的



线程间的通信:

    wait()方法:终端方法的执行,使线程等待

    容易死锁

    notify()方法:唤醒处于等待的某一线程,使其结束等待

    notifyAll()方法:唤醒所有处于等待的线程,使其结束等待


我们利用flag来看是否等待,和唤醒(不唤醒会死锁)


阅读更多

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