博学谷——让IT教学更简单,让IT学习更有效
2) 在Demo类中重写run()方法,在方法内编写一个for循环,循环体内打印:线程名称+循环
次数。
3) 编写测试类Example04,在Example04类的main()方法中,创建一个Demo对象,利用Thread
的构造方法创建三个线程对象并命名,使用setPriority()方法将其中两个线程的优先级设为最大和最小,最后开启三个线程的start()方法。
二、案例实现
class Demo implements Runnable { }
public class Example04 { }
public static void main(String[] args) { }
Demo d = new Demo();
Thread t1 = new Thread(d,\杨过\Thread t2 = new Thread(d,\岳不群\Thread t3 = new Thread(d,\金龙\//设置线程的优先级
t3.setPriority(Thread.MAX_PRIORITY); t2.setPriority(1); t1.start(); t2.start(); t3.start(); public void run() { }
for (int x = 0; x < 5; x++) { }
System.out.println(Thread.currentThread().getName() + \
运行结果如图5-4所示。
图5-4
运行结果
6
博学谷——让IT教学更简单,让IT学习更有效
三、案例总结
1、在多线程程序中,可以通过设置线程的优先级别来控制线程获得CPU执行的几率。
2、线程的优先级用1~10之间的整数来表示,数字越大优先级越高。也可以使用静态常量表示线程的优先级,如:MAX_PRIORITY、MIN_PRIORITY、NORM_PRIORITY。
3、虽然Java中提供了10个线程优先级,但是这些优先级需要操作系统的支持,不同的操作系统对优先级的支持是不一样的,不能很好的和Java中线程优先级一一对应,因此,在设计多线程应用程序时,其功能的实现一定不能依赖于线程的优先级,而只能把线程优先级作为一种提高程序效率的手段。
案例5-5 线程休眠
一、案例描述
1、 考核知识点
编 号:00105008 名 称:线程休眠
2、 练习目标
? 了解线程休眠的概念和作用
? 掌握如何使用sleep(long millis)方法使线程休眠
3、 需求分析
如果希望人为地控制线程,使正在执行的线程暂停,将CPU让给别的线程。这时,可以使用静态方法sleep(long millis),该方法可以让当前正在执行的线程暂停一段时间,进入休眠等待状态。为了让初学者更好地掌握线程休眠,案例中将启动三个线程共同出售10张票来演示线程休眠及休眠引发的结果。
4、 设计思路(实现原理)
1) 自定义一个类Ticket,使其实现Runnable接口,并在该类中创建int类型私有属性tickets,
赋初值为10。
2) 在Ticket类中重写run()方法,在方法内编写一个while循环。循环体内判断ticket值,当大
于0时,使用sleep(long millis)方法使线程休眠1秒钟,并打印:当前线程名称+“正在出售第”+循环次数;否则结束循环。每执行一次while循环,tickets值减一。 3) 编写测试类Example05,在Example05类的main()方法中,创建一个Ticket对象,利用Thread
的构造方法创建三个线程对象并命名,并开启三个线程的start()方法。
二、案例实现
class Ticket implements Runnable {
private int tickets = 10; public void run() {
while (true) {
if (tickets > 0) {
try {
7
博学谷——让IT教学更简单,让IT学习更有效
}
public class Example05 { }
public static void main(String[] args) { }
Ticket tr = new Ticket(); Thread t1 = new Thread(tr); Thread t2 = new Thread(tr); Thread t3 = new Thread(tr); t1.setName(\窗口1\t2.setName(\窗口2\t3.setName(\窗口3\t1.start(); t2.start(); t3.start(); }
}
}
}
System.out.println(Thread.currentThread().getName() + \正在出售第\张票\
Thread.sleep(1000); e.printStackTrace();
} catch (InterruptedException e) {
运行结果如图5-5所示。
图5-5 运行结果
从运行结果可以看出,当程序启动后,“窗口1”、“窗口2”、“窗口3”线程共同出售tikcets,但是最后“窗口1”出售了第0张票、“窗口3”出售了第-1张票,从中可以推断当tickets=1时,某一个线程进入if分支语句后,线程休眠了1秒。在此期间,tickets的值依然为1,其他两个线程也顺利进入了到if分支语句中,当线程休眠时间结束后,三个线程分别操作了ticket值,所以造成了tickets值为负数。
三、案例总结
1、sleep(long millis)方法声明抛出InterruptedException异常,因此在调用该方法时应该捕获异常,或者声明抛出该异常。
8
博学谷——让IT教学更简单,让IT学习更有效
2、sleep()是静态方法,只能控制当前正在运行的线程休眠,而不能控制其它线程休眠。当休眠时间结束后,线程就会返回到就绪状态,而不是立即开始运行。
案例5-6 线程让步
一、案例描述
1、 考核知识点
编 号:00105009 名 称:线程让步
2、 练习目标
? 了解线程让步的概念和作用 ? 掌握设置线程让步的方法
3、 需求分析
在校园中,我们经常会看到同学互相抢篮球,当某个同学抢到篮球后就可以拍一会,之后他会把篮球让出来,大家重新开始抢篮球,这个过程就相当于Java程序中的线程让步。在多线程程序中,可以通过线程的yield()方法将线程转换成就绪状态,让系统的调度器重新调度一次,达到线程让步的目的。案例中将在一个多线程程序中,通过yield()方法对其中一个线程设置线程让步来演示。
4、 设计思路(实现原理)
1) 自定义一个类Demo,使其实现Runnable接口。
2) 在Demo类中覆写run()方法,在方法内编写一个for循环,循环体内,先执行线程让步的方
法yield(),然后输出打印:线程名称+循环次数。 3) 编写测试类Example06,在Example06类的main()方法中,创建一个Demo对象,利用Thread
的构造方法创建两个线程对象,并执行线程对象的start()方法,同时编写for循环,循环内打印“main:”+当前循环次数。
二、案例实现
class Demo implements Runnable{ }
public class Example06 {
public static void main(String[] args)throws Exception {
Demo d = new Demo(); Thread t0 = new Thread(d); Thread t1 = new Thread(d);
9
public void run(){ }
for(int x = 0 ; x < 5 ; x++){ }
Thread.yield();
System.out.println(Thread.currentThread().getName()+\
博学谷——让IT教学更简单,让IT学习更有效
}
}
t0.start(); t1.start();
for(int x = 0 ; x<5 ; x++){ }
System.out.println(\
运行结果如图5-6所示。
图5-6
运行结果
三、案例总结
1、在多线程程序中,可以通过设置线程让步,让系统的调度器重新调度一次CPU的分配。
2、线程让步和线程休眠是不一样的,线程让步不会阻塞该线程,它只是将线程转换成就绪状态,而线程休眠,是让线程在一定时间内进入休眠等待状态,到达时间后线程再转换成就绪状态。
案例5-7 线程插队
一、案例描述
1、 考核知识点
编 号:00105010 名 称:线程插队
2、 练习目标
? 了解线程插队的概念和作用 ? 掌握线程插队方法的使用
3、 需求分析
在火车站买票的时候,有的乘客着急赶火车,会插到队伍前面先买车票,其他乘客再买票。那么在多线程程序中,也可以通过线程插队,让插队的线程先执行完,然后本线程才开始执行。在案例中将通过使用join()方法来演示线程插队。
4、 设计思路(实现原理)
1) 自定义一个类Demo,使其实现Runnable接口。
10