线程:“程序中一个单一的顺序控制流程”,这种官方的解释可能不太容易理解,换句话说线程其实是程序的一条执行的路线。而我们所说的多线程,则是程序内部有多条执行路线同时执行的一种机制。
在我们认识多线程之前,我们所写的代码只能是一行行代码的去顺序执行(即使是循环也不可能同时执行两行代码),而有了多线程机制则不同了,我们可以控制CPU“同时”执行两个及以上的功能块代码,就仿佛一条水流多了几条分支,这几条水流同时在各自的区域内流动。这里的同时之所以加上引号,是因为一个CPU某个时刻是只能执行一个线程的。
(这里说同时执行两个及以上,是因为CPU的运行速度是非常快的,它可以在多个线程间进行切换,对用户来说就仿佛值在同时执行着多条线程,同时也存在另外一种情况,一台计算机配有多个CPU,一个CPU处理一个线程,多个CPU同时可处理多条线程,这样对用户来说也是计算机在同时进行这多条线程。)
在初步认识了线程的概念后,我们有必要了解一下它的“长辈”——进程。进程代表着计算机中程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。在当代面向线程设计的计算机结构中,进程是线程的容器。
打开任务管理器,我们可以看到有一个名叫“进程”的选项卡,在它下面有我们计算机正在运行着的N多个程序,因此可以说进程是运行程序过程的抽象,它可以动态的创建,也可以动态的消亡。进程与线程的主要区别和联系是:进程可以申请和拥有独立的资源,而进程内的线程可以共享这些资源。
java中使用Thread类来表示线程,要新建一个线程,便是将Thread实例化一个对象,此时创建出的线程并没有得到真正执行,我们需要调用Thread对象的start对象才能真正启动其线程:
方式一:
//实例化继承Thread的匿名类对象 Thread thread = new Thread(){ //重写run方法,线程启动后执行的代码片段 @Override public void run() { while(true){ try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("1:" + Thread.currentThread().getName()); } } }; thread.start();
方式二:
Thread thread2 = new Thread(new Runnable(){ @Override public void run() { while(true){ try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("2:" + Thread.currentThread().getName()); } } }); thread2.start();
从两小段程序中我们可以看到,调用Thread的start()方法,才开始执行线程的功能段,也就是run方法内的代码,实际上在调用了start方法后,线程是处于就绪状态,也就是等待操作系统进行调度的状态,当CPU真正处理这个线程时才算是真正的运行状态。
在线程运行过程中可能出现资源不足或条件不符合运行要求时,线程将进入阻塞状态,知道条件或资源满足时才继续执行。
线程的几种状态及其相互间转换如下图:
本篇文章介绍了线程的整体概念以及在java中如何创建线程,只有清楚自己程序内部执行流程,才有可能控制并明确系统的脉络。