第一批博文解释

——对于线程部分博文的解释


第一部分是线程相关博客的连载

  • 探索多线程
  • 初步尝试解决线程冲突
  • 思考与再度尝试
  • 线程不安全问题与对象锁的探索
  • 单线程实现多线程功能

cmd-markdowm-logo

  • 申明,第一部分的博文里面的代码使专门为小白设计,形象生动的解释了多线程之间为什么冲突,直白的说就是为了这几篇文章编写的代码,请大家不要纠结于这些代码在生活生产中是否有用,仅供理论研究

对于第一篇博文的解释

        第一部分,我让每个线程同时操作同一个对象Graphics g,意图就是想说明线程冲突往往和访问同一物理地址有关,或者对于java来说,是使用同一个对象的引用副本有关。
每一个球颜色随机就是为了区分每一个线程。
通过小球的颜色画错来说明线程冲突的本质。

对于第二篇博文的解释

        由于不同线程访问同一个对象会造成一些问题,有时候这些问题是致命的,所以对于初学者来说,可以选择适当避免多线程同时操作一个对象,这里用一个线程专门操作一个对象来作为示例(本例以一个线程专门使用Graphics g来画图)。
所以这是对于线程冲突的初步尝试

对于后面几篇关于线程的博文

        to be continuing

        敬请期待~

  • 后续会连载java数据回收机制等理论相关博客,也会连载数据结构与算法的博文。

类多线程的单线程之解决冲突初尝试

类多线程的单线程之解决冲突初尝试 | Gragon Atlas

——对线程冲突的尝试性主观能动的处理

        之前我们一起探索了多线程实现奥秘,知道原理后,我们就可以根据原理来解决之前那个画球的问题。既然各个线程被打碎成了碎片,这些碎片虽然还是具有电脑逻辑的完整性,但是已经不具备人类思维逻辑完整性了,所以它会把我们认为是一体的代码拆开,按照它自己的逻辑组合,所以难免导致程序逻辑上出现问题,虽然计算机并没有出错。所以,我们可以把我们自己认为是逻辑统一且不可分割的部分作为一个“模块”,这些模块在一定程度上保留其完整性的执行。所以,首先我们可以尝试来完成一个简单的“模块”,在此之前,为了在一个线程里画n多个球(n和点击按钮次数有关),我们先建一个类:

        虽然计算机为了实现多进程,不可避免地还是把它打碎成碎片,但是由于是一个线程去完成的,所以在一定程度上保留了逻辑完整性。

        所以,我们还需要在监听器里面做一些修改,只初始化一个监听器,每次点击按钮就初始化一个小球,并添加进线程的小球队列:

    然后激动人心的时刻到了,我们试着运行一下:

图四

        小球的颜色没有乱,而且也没有“残影”!

        虽然只是一些小小的改动,但是初次尝试的效果显而易见。

类多线程的单线程之探索多线程

类多线程的单线程之探索多线程 | Gragon Atlas

——关于对多线程实现机制的探索

        在第一次接触多线程的时候,很多小伙伴可能知道多个线程可以并发工作,但是不知道多线程实现的本质。如果让一个刚刚学多线程的同学写一个运动的小球,那么大概他会先写一个界面:

        然后是监听器,监听那个按钮

        然后是线程

    然后效果就是

图一

图二

图三

        结果是,不仅小球的颜色会改变,而且还会留下其他小球颜色的“残影”,那么这到底是为什么呢?

        通过分析java多线程的实现,我们可以提出这么一个假设,假设其实程序在一瞬间只能执行一个任务,但是它可以将多个任务分解成一个个碎片,按照一定的顺序轮流执行。由于这个“一瞬间”十分短暂,对于人类来说,这样的方式执行的效果几乎就是多个任务同时进行。如果是这样,就可以非常好的解释了这个现象。现在我们来用假设和实验事实互相证明: 这个是绘制的代码:

        当线程1执行到①的时候,系统切换到了线程2,线程2也执行了①,由于我之前设定的是每个球的颜色是随机的,所以当系统切换回线程1的时候,再去执行①后面语句时,画出来的球的颜色就和线程②的小球是一样的了,这也就是为什么图二里面最左边的球颜色会变成最右边的球的颜色了。

        当线程1执行到②的时候,系统又切换到了线程2,线程2执行了①,然后当系统再次切换回线程1的时候,本来执行②后面的语句来抹去上一个球,但是由于颜色变成了线程2的小球的颜色,便画出了一个颜色和线程2小球一样的影子。

        这个实例告诉我们,其实多线程不是完全同时进行的,电脑也无法在同一时刻做那么多任务,所以当多个线程按照特定的权打成碎片,系统按照一定顺序轮流完成碎片,这便是我们看到的多线程。知道事实的我们是不是可以自己动手模仿着写一个类似功能的算法呢?