多线程

Java基础day12笔记:多线程(守护线程)|多线程(join

2018-12-17  本文已影响0人  楠楠喜欢泡枸杞

    08-多线程(守护线程)

        接下来说一下Thread类中的其他方法。

        点进去看一看:

        我们试一下~

        先将它注释掉运行一下:

        发现程序停在这里不动了。

        我们将它们标记成守护线程:

        编译运行:

        结束啦。

        守护线程其实不是很好理解,其实应该叫做后台线程。我们所能看到的线程都是前台线程,当把某些线程标记成后台后,它就具备了某些含义。

        后台线程的特征是:开启后和前台线程一起共同争夺cpu的执行权。

        它和前台线程在开启、运行上都没有区别,就结束有区别。

        当所有的前台线程都结束后,后台线程会自动结束。有一点依赖前台线程的感觉。

        而在这个例子中,主线程是前台线程,前台线程结束后,Thread0和Thread1自动结束。

        后台线程就是守护线程,跟着前台线程跑,前台线程挂了,它也就挂了。

        总结一下守护线程设置的方法setDaemon:

        1,该方法必须在启动线程前调用。

        2,当正在运行的线程都是守护线程时,Java虚拟机退出。

    09-多线程(Join方法)

        再接着看,还是方法~

        刚刚讲interrupt方法时,它里面有提到join:

        join是什么呢?

        点进去看看:

        写个例子并运行:

        发现几个线程在交替运行。

        现在加上join:

        编译运行:

        我们发现Thread0一直执行到69,之后main和Thread1才交替执行。

        所以join是什么意思呢?

        主线程读到t1.join();时,叫做t1要申请加入到运行中来。更确切的说,t1要cpu的执行权。此时主线程就把执行权放出来了,给了t1。这时主线程处于了冻结状态。t1执行完之后,主线程才恢复到运行状态中。

        join方法有什么用呢?

        当我们在进行多线程运算的时候,一个线程在运行过程中,我们可以临时加入另一个线程,让新加入的线程运算完之后,旧的线程再继续运行。

        我们再试试,将t1.join()放在下面会发生什么现象。

        分析一下:

        主线程依次开启了t1、t2线程,当执行到t1.join时,t1就加入了,这个时候主线程就停下来了,冻结了,而t1拿到了执行权,注意,主线程碰到t1是释放了执行权。而此时有两个线程还活着,t1和t2,都具备执行资格,这个时候cpu就对t1和t2交替执行。那主线程什么时候活呢?它要等到t1结束才能活,至于t2是否结束,跟主线程没有关系。如果t1结束了,主线程活了,而t2还没有结束,这时主线程就在跟t2抢执行权。所以,主线程碰到谁的join,它就等谁。

        总结一下:

        join:

        当A线程执行到了B线程的.join()方法时,A就会等待,等B线程都执行完,A才会执行。

        join可以用来临时加入线程执行。

        还有个问题:

        主线程遇到了t1的join,主线程就冻结了,万一t1在运行过程中挂了呢(wait)?

        t1只要一wait主线程就挂了。

        这个时候为什么interrupt能清除冻结状态呢?它能把主线程的状态清除掉,清除完以后,t1挂着,主线程也能运行,不用为了等t1而死。而强制让它活过来,就会发生异常。(这里有点乱,还要理一理

    10-多线程(优先级&yield方法)

        Thread类中有一个方法:

        试一下:

        我们会看到Thread1,优先级是5,所属的线程组是main。(一般来说,谁开启的这个线程,这个线程所属的线程组就是开启它的那个线程)

        当然我们也可以手动设置线程组:

        我们只要new一个这个对象,将所需要的线程封装到这个组中就OK。

        当然,开发中几乎用不到这个,因为用起来挺麻烦的。所以就不细讲啦。

        接下来再说优先级。

        优先级代表着抢资源的频率。

        优先级越高,则主线程执行它的频率越高。

        默认的优先级是5。

        如果不喜欢5,可以改,设置优先级的方法:

.

        那可以调成10000吗(认真脸)?

        优先级最高是10级喔。

        相邻的优先级其实差别不大,比如5和6,频率都差不多。

        而跨度最明显的3个优先级为1,5,10。

        所以,还给它们起了名称:

        它们都是静态的常量:

        我们试一下:

        一般运行次数越多,优先级体现的越明显。(当然,即使优先级很高,也不可能一直霸着cpu)

        顺便再提一下yeild方法:

        试一下:

        我们发现Thread0和Thread1在交替执行。

        0进去之后,读到Thread.yield(),会主动放弃,让1进来,1读到Thread.yield(),也会主动放弃,让0进来,就这样交替着执行。

        这样可以减缓一下线程的运行,可以达到让线程运行的频率都差不多的效果。这个也不是很常用喔。

        再来一个例子:

        如果前面的循环量级非常高的话,后面的循环几乎就执行不到了。

        可是我们学了多线程,当需要几段代码同时运行时,将它们封装到单独的线程中:

        这里用了匿名类,因为用它更方便快捷一些。

上一篇下一篇

猜你喜欢

热点阅读