線程
1.程序和程序的關系與差別,是了解線程概念的前提
程序
應用程式執行的執行個體
有獨立的記憶體空間和系統資源
線程
CPU排程和分派的基本機關
執行運算的最小機關
2.什麼是多線程
如果在一個程序中同時運作了多個線程,用來完成不同的工作,則稱之為“多線程”
多個線程交替占用CPU的資源,而非真正的并執行
多線程好處,
充分利用CPU的資源,提高代碼性能
簡化程式設計
Thread類
主線程
main()方法即為主線程入口
産生其他子線程 的線程
必須最後完成執行,因為它執行各種關閉動作
線程建立的兩種方法
1.繼承thread類
編寫簡單,可直接操作線程
(1)建立MyThread類繼承Thread類 ,并重寫run()方法
package thread_21;
//建立并啟動線程
public class MyThread extends Thread{
public void run() {
for(int i=1;i<=100;i++){
System.out.println(Thread.currentThread().getName()+":"+i);
}
}
}
(2)編寫測試類TestThread
package thread_21;
//測試類
public class TestThread {
public static void main(String[] args) {
// TODO Auto-generated method stub
//建立線程對象
MyThread myThread=new MyThread();
MyThread myThread2=new MyThread();
//啟動線程
//搶占CPU
// myThread.start();
// myThread2.start();
//是否可以調用run()方法啟動線程?
//(1)隻有主線程一個執行路徑(2)一次調用兩次run()方法
//run()方法被當作main()中的一個普通方法執行,失去了線程的意義
myThread.run();
myThread2.run();
}
}
2.實作Runnable建立線程
(1)定義MyRunnable類實作Runable接口
package thread_21;
//建立線程 :實作Runnable接口
public class Mthread2 implements Runnable{
}
(2)實作run()方法,編寫
package thread_21;
//建立線程 :實作Runnable接口
public class Mthread2 implements Runnable{
public void run() {
for(int i=1;i<=100;i++){
System.out.println(Thread.currentThread().getName()+":"+i);
}
}
}
(3)建立線程對象 ,調用start()方法啟動線程
package thread_21;
//測試線程
public class TestThread2 {
public static void main(String[] args) {
//建立線程對象
Runnable runnable=new Mthread2();
Thread thread=new Thread(runnable);
Thread thread2=new Thread(runnable);
//啟動線程
thread.start();
thread2.start();
}
}
調用run()和start()方法建立線程的差別:
使用start()方法主線程和子線程并行交替執行
使用run()方法,隻有主線程一條執行

線程的狀态
自定義線程類MyThread ,繼承Runnable類,重寫run()方法,定義5s後線程休眠
package threadstate_22;
public class MyThread implements Runnable{
@Override
public void run() {
System.out.println("線程正在運作!!");
//線程休眠5秒
try {
System.out.println("線程休眠開始,正在阻塞狀态");
Thread.sleep(5000);
System.out.println("線程休眠結束,正在阻塞狀态");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
測試類TestThread
package threadstate_22;
//測試線程的集中狀态
public class TestThread {
public static void main(String[] args) {
// TODO Auto-generated method stub
Runnable runnable = new MyThread();
Thread t = new Thread(runnable);
System.out.println("線程處于建立狀态");
t.start();
System.out.println("線程處于就緒狀态");
}
}
線程排程
1.集中線程排程的方法(作用)
2.如何設定線程優先級
//線程排程
thread2.setPriority(10);
thread.setPriority(1);
thread.setPriority(Thread.MAX_PRIORITY);
thread2.setPriority(Thread.MIN_PRIORITY);
3.掌握如何實作線程休眠
//s:線程休眠的秒數
public static void bySec(long s){
for(int i=1;i<=s;i++){
System.out.println(i+"秒");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
4.join()搶占線程
自定義MyThread類實作Runnable接口,重寫run()方法,循環輸出30個線程名
package threaddispatch;
public class MyThread implements Runnable{
public void run() {
for(int i=1;i<30;i++){
System.out.println(Thread.currentThread().getName()+":"+i);
}
}
}
測試類
package threaddispatch;
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
//建立子線程對象t
Runnable runnable=new MyThread();
Thread t=new Thread(runnable, "myThread");
t.start();
//主線程main做的事情
for(int i=1;i<=20;i++){
System.out.println(Thread.currentThread().getName()+":"+i);
//當i=5的時候,強制把t線程加入執行
//線程排程:join()
//--等待線程終止 ,等待t線程終止:等待t線程執行結束後,main主線程再繼續執行
if(i==5){
try {
t.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
5.使用yield()暫停正在執行的線程對象,并執行其他線程
首先掌握兩點:
(1)這是線程的靜态方法,不需要建立對象,而通過類名.yield()去使用
(2)從某種意義上,join和yield作用相反
使用yield()暫停正在執行的線程對象,并執行其他線程
被暫停的線程對象處于就緒狀态,不轉為阻塞狀态
public static void yield()
多線程共享資料
可能帶來的問題:資料不安全
原因:多線程共同操作資料時,引發的沖突(如延遲時,操作為全部完成等等)
思考:如何解決?
線程同步
實作線程同步的兩種方式
(1)第一種
使用synchronized修飾的方法控制對類成員變量的通路
通路修飾詞 synchronized 傳回類型 方法名 (參數清單){......}
或者
synchronized 通路修飾詞 傳回類型 方法名 (參數清單){......}
synchronized 就是為目前的線程聲明一把鎖
(2)第二種
使用synchronized關鍵詞修飾的代碼塊
synchronized(syncObject){
//需要同步的代碼
}