1. 一些方法
sleep():
sleep()方法能迫使线程休眠指定长的时间。在调用sleep()方法的时候,必须把它放在try块中,因为在休眠时间到期之前有可能被打断。如果某人持有对此线程的引用,并且在此线程上调用了interrupt()方法,就会发生这种情况。
daemon线程:
必须在线程启动之前调用setDaemon()方法,才能把它设置为后台线程。一个后台线程所创建的任何线程都将被自动设置成后台线程,主线程退出以后,守护线程随后也会慢慢退出
join():
一个线程可以在其他线程之上调用join()方法,其效果是等待一段时间直到第二个线程结束才继续执行。如果某个线程在另一个线程t上调用t.join(),此线程将被挂起,直到目标线程t结束才恢复(即t.isAlive()返回为false)
你也可以在调用join()时带上一个超时参数(单位可以是毫秒或者毫秒+纳秒),这样如果目标线程在这段时间到期还没结束的话,join()方法总能返回。
对join()方法的调用可以被中断,做法是在调用线程上使用interrupt()方法,这时需要用到try-catch
isAlive():
如果该线程是可运行线程或被中断的线程,那么该方法返回true;如果该线程仍然是个新线程或尚未成为可运行线程,或者该线程是个死线程,那么该方法返回false
注:无法确定一个“活”线程究竟是处于可运行状态还是被中断状态,也无法确定一个运行线程释放正处在运行之中。另外,你也无法对尚未成为可运行的线程与已经死掉的线程进行区分。
2. 线程的四种状态:创建、就绪、死亡、阻塞。
线程进入阻塞状态可能有如下四种原因:
通过调用sleep()使线程进入休眠状态。在这种情况下,线程在指定时间内不会运行
通过调用wait()使线程挂起,直到线程得到了notify()或notifyAll()消息,线程才会进入就绪状态
线程在等待输入/输出操作的完成
线程试图在某个对象上调用其同步控制方法,但是对象锁不可用
互斥条件:线程使用的资源中至少又一个是不能共享的
至少有一个进程持有一个资源,并且他在等待获取一个当前被别的进程持有的资源。
资源不能被进程抢占。所有的进程必须把资源释放作为普通事件。
必须有循环等待,即,一个线程等待其他线程持有的资源,后者又在等待另一个进程持有的资源,这样一直下去,直到又一个进程在等待第一个进程持有的资源,使得大家都被锁住。
要发生死锁,必须这四个条件同时满足,所以,只要破坏其中任意一个,就可以打破死锁。其中第四个条件是最容易被打破的。
4. 线程的优先级
JVM将线程的优先级映射为主机平台的优先级等级。
每当主机平台使用的优先级低于Java平台时,某个线程的运行就可能被另一个优先级明显低得多的线程线程抢先。这意味着你不能依靠多线程程序中的优先级等级。
另外,调用yield方法,只会让当前线程暂时放弃运行,而主机则始终准备对放弃运行的线程实施重新启动。如果当前线程优先级较高,则可能主机一直重启该线程,而其他低优先级线程将得不到运行。为此,yield也靠不住,sleep可能是更好的方式。
5. java中对以“管道”形式对线程的输入/输出提供了支持
PipedWriter类允许线程向管道写;PipedReader类允许不同线程从一个管道中读取。或是采用PipedInputStream和PipedOutputStream提供字节流支持
使用管道的主要原因是为了使每个线程始终能保持简单。可以将多个线程相互连接起来,而不必担心线程的同步问题。
但要注意,管道式数据流只适用于线程在低层次上的通信,在其他情况下,可以使用队列。