一.线程简介
二.创建线程
1.继承Thread类
Thread类中常用的两个构造方法如下:
public Thread():创建一个新的线程对象。
public Thread(String threadName):创建一个名称为threadName的线程对象。
继承Thread类创建一个新的线程的语法如下:
public class ThreadTest extends Thread{
}
【例20.1】让线程循环打印1~10的数字
代码:
结果:
2.实现Runnable接口
实现Runnable接口的语法如下:
public class Thread extends Object implements Runnable
Thread类中有以下两个构造方法:
public Thread(Runnable target)
public Thread(Runnable target,String name)
这两个构造方法的参数中都存在Runnable实例,使用以上构造方法就可以将Runnable实例与Thread实例相关联。
使用Runnable接口启动新的线程的步骤如下:
(1)建立Runnable对象。
(2)使用参数为Runnable对象的构造方法创建Thread实例。
(3)调用start()方法启动线程。
【例20.2】让窗口中的图标动起来
代码:
结果:
三.线程的生命周期
要使线程处于就绪状态,有以下几种方法:
(1)调用sleep()方法。
(2)调用wait()方法。
(3)等待输入/输出完成。
当线程处于就绪状态后,可以用以下几种方法使线程再次进入运行状态:
(1)线程调用notify()方法。
(2)线程调用notifyAll()方法。
(3)线程调用interrupt()方法。
(4)线程的休眠时间结束。
(5)输入/输出结束。
四.操作线程的方法
1.线程的休眠
sleep()方法的语法如下:
try{thread.sleep(2000);
}catch(InterruptedException e){e.printStackTrace();
}
【例20.3】每0.1秒绘制一条随机颜色的线条
代码:
结果:
2.线程的加入
如果当前某程序为多线程程序,假如存在一个线程A,现在需要插入线程B,并要求线程B先执行完毕,然后再继续执行线程A,此时可以使用Thread类中的join()方法来完成。
【例20.4】让进度条A等待进度条B
代码:
结果:
3.线程的中断
如果线程是因为使用了sleep()或wait()方法进入了就绪状态,可以使用Thread类中interrupt()方法使线程离开run()方法,同时结束线程,但程序会抛出InterruptedException异常,用户可以在处理该异常时完成线程的中断业务处理,如终止while循环。
【例20.5】单击按钮停止进度条滚动
代码:
4.线程的礼让
Thread类中提供了一种礼让方法,使用yield()方法表示,它只是给当前正处于运行状态的线程一个提醒,告知它可以将资源礼让给其他线程,但这仅是一种暗示,没有任何一种机制保证当前线程会将资源礼让。
五.线程的优先级
线程的优先级可以使用setPriority()方法调整,如果使用该方法设置的优先级不在1~10,将产生IllegalArgumentException异常。
【例20.6】观察不同优先级的线程执行完毕顺序
代码:
结果:
六.线程同步
1.线程安全
例,在项目中创建ThreadSafeTest类,该类实现了Runnable接口,在未考虑到线程安全问题的基础上,模拟火车站售票系统的功能代码
代码:
结果:
2.线程同步机制
1.同步块
Java中提供了同步机制,可以有效地防止资源冲突。同步机制使用synchronized关键字,使用该关键字包含的代码块称为同步块,也称为临界点,语法如下:
synchronized(Object){}
【例20.7】开发线程安全的火车售票系统
代码:
结果:
2.同步方法
同步方法就是在方法前面用synchronized关键字修饰的方法,其语法如下:
synchronized void f(){}
当某个对象调用了同步方法时,该对象上的其他同步方法必须等待该同步方法执行完毕后才能被执行。必须将每个能访问共享资源的方法修饰为synchronized,否则就会出错。
修改例20.7的代码,将共享资源操作放置在一个同步方法中,代码如下:
结果: