【java多线程学习】多线程的基本概念

        今天开始系统的学习了java多线程有关的基础知识,大致先分为三个步骤:多线程的基本概念,多线程的两种使用方法(继承Thread类、实现Runable接口),线程的同步。这里先记录下下多线程的基本概念。几篇比较好的博文 Java多线程编程总结(转载)     .NET多线程编程(1):多任务和多线程  Java多线程编程详解

一:线程和进程的区别

       说多线程(MultiThread)和多进程(MultiProcess)之前先说说多任务(MultiTask),我的理解是多线程和多进程都是操作系统多任务特性的一种实现方法(多线程程序在较低的层次上扩展了多任务的概念)。 早期操作系统只能只能在一段时间点执行单个任务,该任务执行完毕后在执行下一个任务,后来出现了分时操作系统。 一个CPU虽然也还是只能在一个时间点执行一条指令,但是分时操作系统将CPU的时间分成多个片段,每个任务能轮流占用一个片段。任务在其分配的时间片内没有执行完时,则进入等待队列,直到轮流分到下一个时间片。 这样的话,在宏观上看来,计算机就可以同时执行多个任务。分时的概念让并发执行的任务数目不再由CPU的数目来限制。

        进程可以理解为一个系统/应用程序的启动。多进程可以直观理解为计算机在浏览网页的同时,也可以QQ聊天,也可以听音乐等。正如在进程管理器中看到的一样,每个启动的程序都有进程名与之对应。如浏览网页的chrome.exe,QQ聊天的QQ.exe,听音乐的DoubanRadio.exe等。 这样多进程在较高的程度上实现了多任务的概念。每个进程程序都有自己的堆栈空间和环境变量设置等,互不干扰。 比如word中设置字体颜色为黑色,并不影响QQ聊天中的字体颜色设置为蓝色的特性。

     线程可以理解为一个程序中的执行流,或者是一个进程中的单一顺序的执行流,又称为轻量级的进程。线程共享相同的地址空间并共同构成一个大的进程。多线程程序是指一个程序中包含有多个执行流,它是一种实现并发机制的有效手段。从逻辑的观点上看,多线程意味着一个程序的多个语句块的同时执行。但是多线程并不等于多次启动一个程序,操作系统也不把每个线程当做独立的进程来对待。

      多线程程序的通信非常简单而有效,上下文切换快并且是整个大程序的一部分的切换。线程可以彼此独立执行,一个程序可以同时使用多个线程来完成不同的小任务(大任务对应不同进程之间的任务分配,小任务对应同一个进程中多个线程之间的任务分配)。

多线程直观的理解是:对于现在流行的流媒体技术,可以边下载数据边播放流媒体数据,这是因为流媒体播放器有一个线程在下载数据并且通知另一个线程播放已经到达的多媒体数据;Word编辑器能够实时检查拼写错误,这是有一个线程在接收键盘输入并且以适当的格式显示在屏幕上,而另一个线程在读入输入的文本,分析并标记处错误的部分。但是Chrome浏览器打开多个网页貌似不是多线程而是多进程。  为什么浏览器会使用多进程架构。

      总结:多任务是由操作系统控制同时执行的多个程序,多线程是在一个程序中或者是由一个程序控制同时执行的多个线程。如果很好的利用线程,可以大大的简化应用程序的设计,提高程序的质量和执行效率。
     

二、线程的状态

在Java中有一个Thread类用于实例化一个新的线程,它带有多个方法控制线程的状态和优先级,也有若干常量表示状态和优先级。线程从产生到消失,可以分为Newborn(创建)、Runable(就绪)、Running(运行)、 Blocked(阻塞)和Dead(死亡)等5个状态。

Newborn(创建)状态

指一个线程已经被创建但是未开始执行的一个特殊状态。此时线程可以通过start()方法启动,产生这个线程所需的系统资源,并调用Thread类的run()方法,这样就使得该线程处于可运行的状态,即Runable状态;

Runable状态

表示一个线程正在等待处理器资源,随时可被调用执行。就绪队列中的线程如果比当前正在执行的线程优先级高,则抢占;另外对于线程排队先按优先级由高到低,然后同优先级之间遵循先来先服务的调度原则。

Runing状态

正在运行的状态,Thread类有一个isAlive()方法判断线程是否正在执行的状态中。从运行状态到非运行状态的可能情形有:

  •  主动或被动的释放了对处理器的控制权,进入等待队列
  • 线程调用了yield或者sleep方法。sleep方法的参数为休眠的时间,线程调用sleep方法后不仅可以给同优先级一个运行机会,给低优先级也有机会。但是yield方法只能给同优先级线程机会,如果当时队列中没有同优先级的线程在等待,则调用yield方法没有作用,当前线程将继续执行;
  • 线程待用suspend方法被挂起,该线程必须由其他线程调用resume方法来恢复执行,两个方法是成对使用的,但是都是已经过时的方法. 可以使用wait和notify方法达到同样的效果; suspend/resume是属于Thread类的方法,wait/notify方法时直接object的方法
  • 为等候一个条件变量,线程调用wait方法。停止等待的话,需要包含该条件变量的对象调用notify <唤醒在此对象监视器上等待的单个线程>  或 notifyAll <唤醒在此对象监视器上等待的所有线程> 方法。 
  • 输入输出流发生线程阻塞;

Blocked状态
处于阻塞状态的线程必须由某些事件唤醒才能进入就绪队列,比如是调用sleep方法的话,就必须暂停一段时间,要是被挂起或者是等待消息的话就必须由一外来事件唤醒

Dead状态
不能再进入等待队列,可能是线程执行结束或被强行终止,如调用stop()方法, 但是stop方法已经是过时方法。  stop() 和 suspend() 方法为何不推荐使用?


归纳如下:

  • 一个线程通过new操作实例化之后,进入Newborn状态;
  • 通过调用start方法进入Runable状态,一个处于Runable状态的的线程将被调度执行,执行该线程相应的run方法代码;
  • 通过调用线程(或从object类中继承过来的)sleep或者wait方法,这个线程进入Blocked状态。一个线程也会自行进入阻塞状态;
  • 当run方法执行完毕,或者有一个异常产生,或者执行System.exit方法,则一个线程进入Dead状态;

一个线程的生命周期图(stop方法过时,另外对于任何状态,如果所调用的方法与当前状态不符,都会引起非法状态处理):





     

    

     

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值