美文网首页多线程
Java基础day12笔记:多线程(守护线程)|多线程(join

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

作者: 楠楠喜欢泡枸杞 | 来源:发表于2018-12-17 21:36 被阅读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进来,就这样交替着执行。

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

            再来一个例子:

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

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

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

    相关文章

      网友评论

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

        本文链接:https://www.haomeiwen.com/subject/ifqhkqtx.html