java從誕生開始就明智的選擇了內置對多線程的支持,這使得java語言相比同一時期的其餘語言具備明顯的優點。線程做爲操做系統調度的最小單元,多個線程可以同時執行,這將顯著提高程序性能,在多核環境中表現的更加明顯。可是,過多的建立線程和對線程的不當管理也容易形成問題。java
4.1 線程簡介編程
4.1.1 什麼是線程多線程
在一個進程中能夠建立多個線程,這些線程都擁有各自的計數器、堆棧和局部變量等屬性,而且可以訪問共享的內存變量。處理器在這些線程上高速切換,讓使用者感受這些線程在同時執行。
ide
一個java程序從main方法開始執行,而後按照既定的代碼邏輯執行,看似沒有其餘線程參與,但實際上java程序天生就是多線程程序,性能
public class MultiThread { public static void main(String[] args) { // 獲取Java線程管理MXBean ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean(); // 不須要獲取同步的monitor和synchronizer信息,僅僅獲取線程和線程堆棧信息 ThreadInfo[] threadInfos = threadMXBean.dumpAllThreads(false, false); // 遍歷線程信息,僅打印線程ID和線程名稱信息 for (ThreadInfo threadInfo : threadInfos) { System.out.println("[" + threadInfo.getThreadId() + "] " + threadInfo.getThreadName()); } } }
能夠看到,一個java程序的運行不單單是main方法的運行,而是main線程和多個其餘線程的同時運行。spa
4.1.2 爲何要使用線程操作系統
主要有如下幾點線程
一、更多的處理器核心blog
二、更快的響應時間生命週期
三、更好的編程模型
4.1.3 線程的狀態
java線程在運行的生命週期中可能處於下6種不一樣的狀態,在給定的一個時刻,線程只能處於其中一個狀態。
public class ThreadState { private static Lock lock = new ReentrantLock(); public static void main(String[] args) { new Thread(new TimeWaiting(), "TimeWaitingThread").start(); new Thread(new Waiting(), "WaitingThread").start(); // 使用兩個Blocked線程,一個獲取鎖成功,另外一個被阻塞 new Thread(new Blocked(), "BlockedThread-1").start(); new Thread(new Blocked(), "BlockedThread-2").start(); new Thread(new Sync(), "SyncThread-1").start(); new Thread(new Sync(), "SyncThread-2").start(); } /** * 該線程不斷的進行睡眠 */ static class TimeWaiting implements Runnable { @Override public void run() { while (true) { SleepUtils.second(100); } } } /** * 該線程在Waiting.class實例上等待 */ static class Waiting implements Runnable { @Override public void run() { while (true) { synchronized (Waiting.class) { try { Waiting.class.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } } /** * 該線程在Blocked.class實例上加鎖後,不會釋放該鎖 */ static class Blocked implements Runnable { public void run() { synchronized (Blocked.class) { while (true) { SleepUtils.second(100); } } } } static class Sync implements Runnable { @Override public void run() { lock.lock(); try { SleepUtils.second(100); } finally { lock.unlock(); } } } }