Java 多线程1 烧水开水喝茶案例
用多线程实现一个喝茶功能,喝茶之前必须先烧开水和洗好杯子。
首先Thread的几个方法:
1、sleep()
使当前线程(即调用该方法的线程)暂停执行一段时间,让其他线程有机会继续执行,但它并不释放对象锁。也就是说如果有synchronized同步快,其他线程仍然不能访问共享数据。注意该方法要捕捉异常。
例如有两个线程同时执行(没有synchronized)一个线程优先级为MAX_PRIORITY,另一个为MIN_PRIORITY,如果没有Sleep()方法,只有高优先级的线程执行完毕后,低优先级的线程才能够执行;但是高优先级的线程sleep(500)后,低优先级就有机会执行了。
总之,sleep()可以使低优先级的线程得到执行的机会,当然也可以让同优先级、高优先级的线程有执行的机会。
2、join()
join()方法使调用该方法的线程在此之前执行完毕,也就是等待该方法的线程执行完毕后再往下继续执行。注意该方法也需要捕捉异常。
3、yield()
该方法与sleep()类似,只是不能由用户指定暂停多长时间,并且yield()方法只能让同优先级的线程有执行的机会。
烧水.java:
/** * 烧水开水 * @author Administrator * */ public class T1 implements Runnable{ @Override public void run() { // TODO Auto-generated method stub System.out.println("开始烧水了! "); try { //让当前的线程暂停10秒 期间线程进入阻塞状态 Thread.sleep(5000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("水烧开了 "); } }
洗杯子.java:
public class T2 implements Runnable { @Override public void run() { // TODO Auto-generated method stub for(int i = 0; i <= 10; i++) { System.out.println("开始洗"+i+"只杯子"); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("第"+i+"只杯子洗完了"); } } }
main.java:
import javax.print.attribute.standard.MediaName; public class test { public static void main(String[] args) throws InterruptedException { System.out.println("想喝茶了"); //分别创建烧水和,洗杯子线程 Thread th1 = new Thread(new T1()); Thread th2 = new Thread(new T2()); //分别启动烧水,洗杯子线程 th1.start(); th2.start(); //等待替th1,th2线程执行完,主线程才继续执行 th1.join(); th2.join(); System.out.println("可以喝茶了"); } }
注意线程是抢占式的,特别对于同优先级的线程,这里需要join(),运行结果:
想喝茶了 开始烧水了! 开始洗0只杯子 第0只杯子洗完了 开始洗1只杯子 第1只杯子洗完了 开始洗2只杯子 第2只杯子洗完了 开始洗3只杯子 第3只杯子洗完了 开始洗4只杯子 第4只杯子洗完了 水烧开了 开始洗5只杯子 第5只杯子洗完了 开始洗6只杯子 第6只杯子洗完了 开始洗7只杯子 第7只杯子洗完了 开始洗8只杯子 第8只杯子洗完了 开始洗9只杯子 第9只杯子洗完了 开始洗10只杯子 第10只杯子洗完了 可以喝茶了