初识线程

一,线程与进程

  先来解释一下线程和进程的东西
            1,线程:进程中负责程序执行的执行单元
                        线程本身依靠程序进行运行
                       线程是程序中的顺序控制流,只能使用分配给程序的资源和环境
            2,进程:执行中的程序,一个进程至少包含一个线程。
            3,单线程:程序中只存在一个线程,实际上主方法就是一个主线程
            4,多线程:在一个程序中运行多个任务,目的是更好地使用CPU的资源

二,线程的实现:
            线程的实现有两种,一种是继承Thread类   一种是实现Runable接口

                   如果自己的类已经extends另一个类,就无法直接extends Thread,此时,可以实现一个Runnable接口

                  Thread类本质上是实现了Runnable接口的一个实例,代表一个线程的实例。启动线程的唯一方法就是通过Thread类的start()实例方法。start()方法      是 一个native方法,它将启动一个新线程,并执行run()方法。这种方式实现多线程很简单,通过自己的类直接extend Thread,并复写run()方法,就可以启动     新线程并执行自己定义的run()方法。
      
 三,线程的状态:
            创建(new)状态:准备好了一个多线程的对象
            就绪(runnable)状态:调用了start()方法,等待CPU进行调度
            运行(running)状态:执行run()方法。
            阻塞(blocked)状态:暂停停止执行,可能将线程交给其他线程使用
            终止(dead)状态:线程销毁
           当需要新起一个线程来执行某个子任务时,就创建了一个线程,但是线程创建之后,不会立即进入就绪状态。
           因为线程需要创建一些条件,只有线程运行需要的所有条件都满足了,才进入就绪状态。

         当线程进入了就绪状态后,不代表立即就能获取CPU执行时间,也许此时CPU正在执行其他事情,
          因此需要等待,当CPU执行时间之后,线程便会真正进入了运行状态


 线程在运行状态过程中,可能有多个原因导致当前线程不继续运行下去,比如用户主动让线程睡眠
 睡眠一定时间后再执行,用户主动让线程等待,或者被同步块给阻塞,此时就对应着多个状态:time waiting
 (睡眠或等待一定的时间),waiting(等待被唤醒),blocked(阻塞);
 
 当由于突然中断或者子任务执行完毕,线程就会自动消亡
 
 在有些教程上将blocked,waiting,time waiting统称为阻塞状态,这个也是可以的,只不过这里我想将
 线程的状态和JAVA中的方法调用联系起来,所以将waiting和 time waiting两个状态分离出来。

sleep(睡眠)和wait(等待被唤醒)的区别:
 sleep是Thraed类的方法,wait是Object类中定义的方法。
 Thread.sleep不会导致锁行为的改变,如果当前线程是拥有锁的,那么Threed.sleep不会让线程释放锁
 Thread.sleep和Object.wait都会暂停当前的线程。OS会将执行时间分配给其他线程,区别是,调用wait后
 需要别的线程执行motify/notifyAll才能够重新获得CPU执行时间
 上下文切换
 对于单核CPU来说,CPU在一个时刻只能运行一个线程,当在运行一个线程的过程中转去运行另外一个程序,这个叫做线程上下文切换
 由于可能当前线程的任务并没有执行完毕,所以在切换是需要保存线程的运行状态,以便下次重新切换回来时
 能够来回切换之前的状态运行。举个简单的例子:比如一个线程A正在读一个文件内的内容,正读到文件的有Ibanez,此时需要暂停A
 去执行B,当再次切换线程A的时候,我们不希望线程A又从文件的开头来读取
 
 因此需要记录线程A的运行状态,那么会记录那些数据呢?
 因为下次恢复时要知道在这之前当前线程已经执行到那条指令了。所以需要记录程序计数器的值,另外比如说线程正在进行
 没结束计算的时候被挂起了,那么下次继续执行的时候需要知道之前挂起的变量的值是多少,因此需要记录CPU寄存器的状态。
 所以一般来说,线程上下文切换过程中会记录表程序计数器,CPU寄存器状态等数据
简单来说:对于线程的上下文切换实际上就是 存储和恢复CPU状态的过程,它使得线程执行能够从中断点恢复执行。

虽然多线程可以使得任务执行的效率得到提升,但是由于在线程切换时同样带来一定的开销代价,并且多个线程会导致系统资源占用的增加,所以
在进行编程时要注意哪些因素

线程的常用方法   

 public void start() 使线程开始执行,

JAVA虚拟机调用该线程的run()方法

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zgwzfy.html