线程相关的基本方法有wait,notify,notifyAll,sleep,join,yield等。
1. 线程等待(wait)
调用该方法的线程进入WAITING状态,只有等待另外线程的通知或被中断才会返回,需要注意的是调用wait()方法后,会释放对象的锁。因此,wait方法一般用在同步方法或同步代码块种。
2. 线程睡眠(sleep)
sleep导致当前线程休眠,与wait方法不同的是sleep不会释放当前占用的锁,sleep(long)会导致线程进入TIMED-WAITING
状态,而wait()方法会导致线程进入WAITING
状态
3. 线程让步(yield)
yield会使当前线程让出CPU执行时间片,与其他线程一起重新竞争CPU时间片,一般情况下,优先级高的线程有更大的可能性成功竞争到CPU时间片,但这又不是绝对的,有些操作系统对线程优先级并不敏感。
4. 线程中断(interrupt)
中断一个线程,其本意是给这个线程一个通知信号,会影响这个线程内部的一个中断标识位。这个线程本身并不会因此而改变状态(如阻塞,终止等)。
- 调用interrupt()方法并不会中断一个正在运行的线程。也就是说处于Running状态的线程并不会因为中断而被终止,仅仅改变内部的中断标识位而已。
- 若调用sleep()而使线程处于TIMED-WAITING状态,这时调用interrupt方法,会抛出InterruptedException,从而使线程提前结束TIMED-WAITING状态。
- 许多声明抛出InterruptedException的方法(如Thread.sleep(long mills方法),抛出异常前都会清除中断标识位,所以抛出异常后,调用interrupted()方法将会返回false。
- 中断状态时线程固有的一个标识位,可以通过此标识位安全的终止线程,比如你想终止一个线程thread的时候,可以调用thread.interrupt()方法,在线程的run方法内部可以根据thread.isInterrupted()的值来优雅的终止线程。
5. Join等待其他线程终止
join方法,等待其他线程终止,在当前线程中调用一个线程的join()方法,则当前线程进入到阻塞状态,直到另一个线程结束,当前线程再有阻塞状态转为就绪状态,等待cpu的宠信。
6. 为什么要用join方法?
很多情况下,主线程生成并启动了一个子线程,需要用到子线程返回的结果,也就是需要主线程需要在子线程结束后再结束,这时候就要用到join()方法。
System.out.println(Thread.currentThread().getName()+"线程开始运行");
Thread6 thread1 = new Thread6();
thread1.setName("线程B");
thread1.join();
Systen.out.println("这时thread1执行完毕后才能执行主线程");
7. 线程唤醒(notify)
Object类中的notify()方法,唤醒在此对象监视器上的单个线程,如果所有线程都在此对象上等待,则会选择唤醒其中一个线程,选择是任意的,并在对实现做出决定时发生,线程通过调用其中一个wait()方法,在对象的监视器上等待,直到当前线程放弃此对象上的锁定,才能继续执行被唤醒的线程,被唤醒的线程将以常规方式与 在该对象上主动同步的的其他线程进行竞争。类似的还有notifyAll()方法,唤醒在此监视器上等待的所有线程。
8. 其他方法
- sleep():强迫一个线程睡眠N毫秒。
- isAlive(): 判断一个线程是否存活。
- join(): 等待线程终止。
- activeCount(): 程序中活跃的线程数。
- enumerate(): 枚举程序中的线程。
- currentThread(): 得到当前线程。
- isDaemon(): 一个线程是否为守护线程。
- setDaemon(): 设置一个线程为守护线程。(用户线程和守护线程的区别在于,是否等待主线 程依赖于主线程结束而结束)
- setName(): 为线程设置一个名称。
- wait(): 强迫一个线程等待。
- notify(): 通知一个线程继续运行。
- setPriority(): 设置一个线程的优先级。
- getPriority()::获得一个线程的优先级