什麼是線程:
--線程是進程內的執行單元,是進程裏面更小的調度單元
進程的切換是非常重量級的操作
java當中建立了一個線程,會同等的映射到操作系統層面,所以跟操作系統上的線程是等價的
線程的基本操作
新建線程:
Thread t1 = new Thread(); Thread t1 = new Thread();
t1.start(); t1.run();// 不能開啓線程
Thread.run()的實現target是Runnable接口
public void run() {
if (target != null) {
target.run();
}
}
Thread t1 = new Thread() {
@Override
public void run() {
System.out.println("hello");
}
}
t1.start();
Thread t1 = new Thread(new CreateThread3());
t1.start();
線程終止:
--Thread.stop() 不推薦使用。它會釋放所有monitor
太暴力,有可能會造成數據的不一致
中斷線程:
一:
public void Thread.interrupt() //中斷線程
public boolean Thread.isInterrupted() //判斷是否被中斷
public static boolean Thread.isInterrupted() //判斷是否被中斷,並清除當前中斷狀態
public void run() {
while(true) {
Thread.yield();
}
}
t1.interrupt();// 打個招呼,告訴你這個線程要中斷了
// 優雅的對線程進行中斷,操作結束後才進行中斷,不會造成數據不一致問題
public void run() {
while(true) {
if (Thread.currentThread().isInterrupted()) {
System.out.println("Interrupted");
break;
}
Thread.yield();
}
}
二:
public static native void sleep(long millis) throws InterruptedException
public void run() {
while(true) {
if (Thread.currentThread().isInterrupted()) {
System.out.println("Interrupted");
break;
}
try {
Thread.sleep(2000);
} catch (InterruptedException) {
System.out.println("interrupted When Sleep");
// 設置中斷狀態,拋出異常後會清除中斷標誌
Thread.currentThread.interrupt();
}
Thread.yield();
}
}
掛起(suspend)和繼續執行(resume)進程:
--suspend()不會釋放所
--如果加鎖發生在resume()之前,則死鎖發生
等待線程結束(join)和謙讓(yeild):
public final void join() throws InterruptedException
public final synchronized void join(long millis) throws InterruptedException
public class JoinMain{
public volatile static int i = 0;
public static class AddThread extends Thread{
@Override
public void run() {
for (i = 0; i < 10000000; i++) {
}
}
}
public static void main(String[] args) throws InterruptedException{
AddThread at = new AddThread();
at.start();
at.join();
System.out.println(i);
}
}
join的本質
while (isAlive()) {// 判斷線程是否結束
wait(0);// 讓當前線程等待
}
線程執行完畢後,系統會調用notifyAll(),喚醒所有等待在當前線程上的所有線程
不要在Thread實例上使用wait()和notify()方法
守護線程:
--在後臺默默的完成一些系統性的服務,比如垃圾回收線程、JIT線程就可以理解爲守護線程
--當一個java應用內,只有守護線程時,java虛擬機就會自然退出
Thread t = new Thread();
t.setDaemon(true);// 將線程設置爲守護線程,要在開啓線程之前設置,否則會報非法異常
t.start();
線程優先級:
public final static int MIN_PRIORITY = 1;
public final static int NORM_PRIORITY = 5;
public final static int MAX_PRIORITY = 10;
Thread high = new HightPriority();
Thread low = new LowPriority();
high.setPriority(Thread.MAX_PRIORITY);
low.setPriority(Thread.MIN_PRIORITY);
low.start();
hight.start();
高優先級的線程更容易在競爭中獲勝
基本的線程同步操作
一:
synchronized:
--直接加鎖對象:對給定對象加鎖,進入同步代碼前要獲得給定對象的鎖。
--直接作用於實例方法:相當於對當前實例加鎖,進入同步代碼前要獲得當前實例的鎖。
--直接作用於靜態方法:相當於對當前類加鎖,進入同步代碼前要獲得當前類的鎖。
synchronized是java內置的,所有的實現是在java虛擬機內部實現的,所有操作都是在虛擬機內部進行的
二:
Object.wait() Object.notify()
wait()調用前必須要獲得當前線程的監視器,調用後會釋放當前線程的監視器
notify()調用前必須要先獲得當前線程的監視器
notify:隨機喚醒等待在當前線程上的一個線程
notifyAll:喚醒等待在當前線程上的所有線程