2-线程的调度

来源:互联网 发布:手机光照度测试软件 编辑:程序博客网 时间:2024/06/05 15:55

睡眠sleep

调用sleep方法可以让线程睡眠指定时间,指定时间到达后线程就进入准备状态等待执行,这是使线程让出CPU的最简单的方法之一。

public static void sleep(long millis) throws InterruptedException
public static void sleep(long millis, int nanos) throws InterruptedException

Thread.sleep()为静态方法,在哪个线程里执行该方法,哪个线程就进入睡眠状态。线程醒来后会进入准备状态,不能保证立刻执行,因此睡眠的时间是线程暂停执行的最短时间
Thread.sleep()
可能会抛出java.lang.InterruptedException异常,调用此方法时需要进行异常处理。

通过睡眠可以对线程进行调度,但这种方法是不准确的,一方面计时可能不准确,另一方面如果两个线程同时醒来进入准备状态,不能保证哪个线程会先被调用,所以不能依赖sleep来提供非常精准的定时操作


线程的优先级

Java线程的调度采用了优先级调度策略:优先级高的线程有更大的概率来获取CPU资源而执行,优先级低的线程并不是总不被执行。当前正在执行的线程的优先级一般不会比正在准备状态的线程优先级低,但这是不保证的。
从Java的优先级策略可以看出哪个线程先执行是没有保障的,优先级策略适合宏观调控。比如,计算量大的线程优先级可以设置的低一些,响应用户输入的线程优先级可以设置的高一些来改善性能。

线程优先级用1~10之间的整数表示,默认值为5比如主线程,子线程的初始优先级与其父线程相同。可以通过setPriority()方法设置,该方法是final的,不能重写。

Thread类中的优先级常量:

public static final int MAX_PRIORITY   10public static final int NORM_PRIORITY  5public static final int MIN_PRIORITY   1

 

线程的让步

线程让步就是让出CPU,让其他线程得以执行,有两种方式:
1)只是让出CPU资源,具体让给谁不确定
2)给指定的线程让步,指定的线程没有完成,不能恢复执行

yield方法:

public static void yield()

静态方法使当前正在运行的线程让出CPU资源,回到准备状态,给其他线程执行的机会 但该操作是没有保障的,很可能线程回到准备状态后又立刻被调度进入运行状态,也就是yield让步不一定成功

join()方法:

public final void join() throws InterruptedException
调用join()方法的线程将等待join()所属的线程执行结束才恢复执行
用join()方法进行两个线程之间的让步是有保证的,被让步的线程没有执行完毕,让步的线程不会恢复执行。

public final void join(long millis) throws InterruptedException
public final void join(long millis,int nanos) throwsInterruptedException

调用join()方法的线程将等待指定时间,如果等待时间内join()所属方法没有完成,则解除等待关系;如果还没到指定时间就执行完成了,则原来线程立即恢复执行

守护线程

其实在Java中根本没有单线程程序,就算只开发了主线程,后台还有很多辅助线程,比如线程调度、内存管理,这些后台运行的线程一般称之为守护线程

开发守护线程是要调用线程对象的setDaemon(boolean) 方法即可,方法签名:
public final void setDaemon(boolean on) 
on为true则将线程设为守护线程,false则设为前台(普通)线程

Java运行时环境判断程序是否结束的标准: 是否所有的前台用户线程都执行完毕了,如果所有的前台线程执行完毕,程序退出。 


Java程序启动时至少开启几个线程?

public class Main{public static void main(String[] args){ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();ThreadInfo[] tis = threadMXBean.dumpAllThreads(false, false);for(int i=0;i<tis.length;i++){System.out.println(tis[i].getThreadId()+"-"+tis[i].getThreadName());}}}

运行结果:

5-Attach Listener4-Signal Dispatcher //分发处理发送给JVM信号的线程3-Finalizer //调用对象的finalize方法的线程,就是垃圾回收的线程2-Reference Handler //清除reference的线程1-main //主线程


 

 

0 0