首页 > 编程语言 > 详细

Java学习笔记之多线程(未完)

时间:2020-05-08 09:46:31      阅读:49      评论:0      收藏:0      [点我收藏+]

多线程

什么是线程

操作系统中的多任务(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)状态

  •  

 

Java学习笔记之多线程(未完)

原文:https://www.cnblogs.com/crowned/p/12846974.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!