操作系统中的多任务(multitasking):在同一时刻运行多个程序的能力.例如,在编辑或下载邮件的同时可以打印文件.今天,人们很可能有单态拥有多个CPU的计算机,但是,并发执行的进程数目并不是由CPU数目制约的.操作系统将CPU的时间片分配给每一个进程,给人并行处理的感觉.
多线程程序在较低的层次上扩展了多任务的概念:一个程序同时执行多个任务.通常,每一个任务称为一个线程(thread),它是线程控制的简称.可以同时运行一个以上线程的程序成为多线程程序(multithreaded).
在实际应用中,多线程非常有用.例如,一个浏览器可以同时下载几幅图片.一个web服务器需要同时处理几个并发的请求.图形用户界面(GUI)程序用一个独立的线程从宿主操作环境中收集用户界面的事件.
API:java.lang.Thread
Thread(Runnable target)//构造一个新线程,用于调用给定目标的run()方法
void start()//启动这个线程,将引发调用run()方法。这个方法将立即返回,并且新线程将并发运行
void run()//调用关联Runnable的run方法
API:java.lang.Runnable
void run()//必须覆盖这个方法,并在这个方法中提供索要执行的任务指令
当线程的run方法执行方法体中最后一条语句后,并经由执行return语句返回时,或者出现了在方法中没有捕获的异常时,线程将终止.在Java的早期版本中,还有一个stop方法,其他线程可以调用它终止线程.但是,这个方法现在已经被弃用了.
没有可以强制线程终止的方法.然而,interrupt方法可以用来请求终止线程.
当对一个线程调用interrupt方法时,线程的中断状态将被置位.这是每一个线程都具有的boolean标志.每个线程都应该不时地检查这个标志,以判断是否被中断.
想弄清楚中断状态是否被置位,首先调用静态的Thread.currentThread方法获得当前线程,然后调用isInterruputed方法:
while(!Thread.currentThread().isInterrupted() && more work todo){
do more work
}
但是,如果线程被阻塞,就无法检测中断状态.这是产生InterruptedException异常的地方.当在一个被阻塞的线程(调用sleep或wait)上调用interrupt方法时,阻塞调用将会被Interrupted Exception异常中断.
void interrupt()//向线程发送中断请求.线程的中断状态将被设置为true.如果目前该线程被一个sleep调用阻塞,那么,InterruptedException异常被抛出
注意:有两个非常类似的方法,interrupted和isInterrupted。Interrupted方法是一个静态方法,它检测当前的线程是否被中断。而且,调用interrupted方法会清除该线程的中断状态。另一方面,isInterrupted方法是一个实例方法,可用来检验是否线程被中断。调用这个方法不会改变中断状态。
线程可以有如下6种状态:
New(新创建)
Runnable(可运行)
Blocked(被阻塞)
Waiting(等待)
Timed waiting(计时等待)
Terminated(被终止)
要确定一个线程的当前状态,可调用getState方法。
当用new操作符创建一个新线程时,如new Thread(),该线程还没有开始运行。这意味着它的状态是new。当一个线程处于新创建状态时,程序还没有开始运行线程中的代码。在线程运行之前还有一些基础工作要做。
一旦调用start方法,线程处于runnable状态。一个可运行的线程可能正在运行也可能没有运行,这取决于操作系统给线程提供运行的时间。
一旦一个线程开始运行,它不必始终保持运行。事实上,运行中的线程被中断,目的是为了让其他线程获得运行机会。线程调度的细节依赖于操作系统提供的服务。抢占式调度系统给每一个可运行线程一个时间片来执行任务。当时间片用完,操作系统剥夺该线程的运行权,并给另一个线程运行机会。当选择下一个线程时,操作系统考虑线程的优先级。
现在所有的桌面以及服务器操作系统都使用抢占式调度。但是,像手机这样的小型设备可能使用协作式调度。在这样的设备中,一个线程只有在调用yield方法、或者被阻塞或等待时,线程才失去控制权。
在具有多个处理器的机器上,每一个处理器运行一个线程,可以有多个线程并行运行。当然,如果线程的数目多于处理器的数目,调度器依然采用时间片机制。
记住,在任何给定时刻,一个可运行的线程可能正在运行也可能没有运行(这就是为什么将这个状态称为可运行而不是运行)。
当线程处于被阻塞或等待状态时,它暂时不活动。它不运行任何代码且消耗最少的资源。直到线程调度器重新激活它。细节取决于它是怎样达到非活动状态的。
当一个线程试图获取一个内部的对象锁(而不是java.util.concurrent库中的锁),而该锁被其他线程持有,则该线程进入阻塞状态。当所有其他线程释放该锁,并且线程调度器允许本线程持有它的时候,该线程将变成非阻塞状态
当线程等待另一个线程通知调度器一个条件时,它自己进入等待状态。在调用Object.wait方法或Thread.join方法,或者是等待java.util.concurrent库中的Lock或Condition时,就会出现这种情况。实际上,被阻塞状态与等待状态是有很大不同的
有几个方法有一个超时参数。调用他们导致线程进入计时等待(timed waiting)状态
原文:https://www.cnblogs.com/crowned/p/12846974.html