多线程入门(二)
一、线程调度
假如我们的计算机只有一个CPU,那么CPU 在某一个时刻只能执行一条指令,线程只有得到CPU时间片,也就是使用权,才可以执行指令。那么Java是如何对线程进行调用的呢?
线程有两种调度模型:
•分时调度模型 所有线程轮流使用 CPU 的使用权,平均分配每个线程占用 CPU 的时间片
•抢占式调度模型 优先让优先级高的线程使用 CPU,如果线程的优先级相同,那么会随机选择一个,优先级高的线程获取的 CPU 时间片相对多一些。
我们的线程没有设置优先级,肯定有默认优先级。
那么,默认优先级是多少呢? 线程默认优先级是5。
如何获取线程对象的优先级?
public final int getPriority():返回线程对象的优先级
如何设置线程对象的优先级呢?
public final void setPriority(int newPriority):更改线程的优先级。
线程优先级的范围是:1-10。否则抛出IllegalArgumentException:非法参数异常
线程优先级高仅仅表示线程获取的 CPU时间片的几率高,但是要在次数比较多,或者多次运行的时候才能看到比较好的效果。
二、线程控制
已经知道了线程的调度,接下来我们就可以使用如下方法对象线程进行控制
1.线程休眠(暂停一定时间)
public static void sleep(long millis)
2.线程加入
public final void join()//等待该线程终止。ThreadJoin tj1 = new ThreadJoin(); ThreadJoin tj2 = new ThreadJoin(); ThreadJoin tj3 = new ThreadJoin(); tj1.start(); try { tj1.join(); } catch (InterruptedException e) { e.printStackTrace(); } tj2.start(); tj3.start();
那么只有等tj1线程结束后 tj2 和tj3才会开始执行
3.线程礼让
public static void yield() //暂停当前正在执行的线程对象,并执行其他线程。
4.后台线程
public final void setDaemon(boolean on):将该线程标记为守护线程或用户线程。
当正在运行的线程都是守护线程时,Java 虚拟机退出。 该方法必须在启动线程前调用。
5.中断线程
public final void stop():让线程停止,过时了,但是还可以使用。
public void interrupt():中断线程。 把线程的状态终止,并抛出一个InterruptedException。
Thread.interrupt() VS Thread.stop()
这两个方法最大的区别在于:interrupt()方法是设置线程的中断状态,让用户自己选择时间地点(???)去结束线程;而stop()方法会在代码的运行处直接抛出一个ThreadDeath错误,这是一个java.lang.Error的子类。所以直接使用stop()方法就有可能造成对象的不一致性。
interrupt方法:
实际上,在JAVA API文档中对该方法进行了详细的说明。该方法实际上只是设置了一个中断状态,当该线程由于下列原因而受阻时,这个中断状态就起作用了:(1)如果线程在调用 Object 类的 wait()、wait(long) 或 wait(long, int) 方法,或者该类的 join()、join(long)、join(long, int)、sleep(long) 或 sleep(long, int) 方法过程中受阻,则其中断状态将被清除,它还将收到一个InterruptedException异常。这个时候,我们可以通过捕获InterruptedException异常来终止线程的执行,具体可以通过return等退出或改变共享变量的值使其退出。(2)如果该线程在可中断的通道上的 I/O 操作中受阻,则该通道将被关闭,该线程的中断状态将被设置并且该线程将收到一个 ClosedByInterruptException。这时候处理方法一样,只是捕获的异常不一样而已。
因为调用interrupt方法后,会设置线程的中断状态,所以,通过监视该状态来达到终止线程的目的。总结:程序应该对线程中断作出恰当的响应。响应方式通常有三种:(来自温绍锦(昵称:温少):http//www.cnblogs.com/jobs/)