本文主要記錄了一些本人學習多線程的一下筆記,可作爲多線程入門參考。
一、線程簡介
請看:https://blog.csdn.net/qq_33157666/article/details/103949005
二、線程狀態
線程的狀態主要包括:
2.1 線程休眠_sleep
- sleep(時間)指定當前線程阻塞的毫秒數(1000=1秒);
- sleep存在異常InteruptedException;
- sleep時間達到後線程進入就緒狀態;
- sleep可以模擬網絡延時、倒計時等;
- 每一個對象都要一個鎖,sleep不會釋放鎖。
//模擬倒計時
public class TestSleep2{
public static void main(String[] args) {
try {
tenDown();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void tenDown() throws InterruptedException{
int num=10;
while(true){
Thread.sleep(1000);
System.out.println(num--);
if(num<=0){
break;
}
}
}
}
運行結果:
2.2 線程禮讓_yield
- 禮讓線程,讓當前正在執行的線程暫停,但不阻塞;
- 將線程從運行狀態改爲就緒狀態;
- 讓cpu重新調度,禮讓不一定成功;
/**
* 測試禮讓線程
* 禮讓不一定成功,看cpu心情
*/
public class TestYield {
public static void main(String[] args) {
MyYield myYeild=new MyYield();
//如果禮讓成功,第一個線程執行到一半時,會讓給第二個線程,否則等第一個線程執行完再執行第二個線程
new Thread(myYeild,"a").start();
new Thread(myYeild,"b").start();
}
}
class MyYield implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"線程開始執行");
Thread.yield();//線程禮讓
System.out.println(Thread.currentThread().getName()+"線程停止執行");
}
}
運行結果:
1、禮讓失敗
2、禮讓成功
2.3 線程強制執行_join
- join可以理解爲插隊
- join合併線程,待此線程執行完成後,在執行其他線程,其他線程阻塞
/**
* 測試join方法
* 想象爲插隊
*/
public class TestJoin implements Runnable{
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
System.out.println("線程vip來了"+i);
}
}
public static void main(String[] args) throws InterruptedException {
//啓動線程
TestJoin testJoin=new TestJoin();
Thread thread=new Thread(testJoin);
thread.start();
//主線程
for(int i=0;i<500;i++){
if(i==200){
thread.join();//插隊
}
System.out.println("main="+i);
}
}
}
運行結果:
可以看到當主線程運行到第200的時候,子線程開始插隊執行到結束,主線程纔開始執行,所以在開發過程中,要謹慎使用join,因爲會影響程序執行效率。
2.4 線程停止
原stop有缺陷,已停止使用,現在分享一種使用修改標誌位,讓線程停止的方法
/**
* 使用修改標誌位的方式,停止線程
*
*/
public class TestStop implements Runnable{
int i=0;
//標誌位,默認爲ture,不停止
Boolean flag=true;
@Override
public void run() {
while (flag) {
System.out.println("Run Theard"+i++);
}
}
//將標誌位改爲false
public void stop(){
flag=false;
}
public static void main(String[] args) {
TestStop testStop=new TestStop();
new Thread(testStop).start();
for (int i = 0; i < 100; i++) {
System.out.println("main i="+i);
if(i==90){
//調用stop方法,修改標誌位,讓線程停止
testStop.stop();
System.out.println("線程該停止了");
}
}
}
}
運行結果如下:
從圖片中可以看出,當i=90時,停止了線程,只剩下主線程自己執行
2.5 觀察線程的狀態
/**
* 觀察測試線程的狀態
*
*/
public class TestState implements Runnable{
public static void main(String[] args) throws InterruptedException {
Thread thread=new Thread(new TestState());
//觀察狀態
Thread.State state=thread.getState();
System.out.println("1---"+state);//NEW
//觀察啓動後
thread.start();
state=thread.getState();
System.out.println("2--"+state);//Run
while(state!= Thread.State.TERMINATED){//只要線程不終止,就一直輸出狀態
Thread.sleep(100);
state=thread.getState();//更新線程狀態
System.out.println("3--"+state);//輸出狀態
}
}
@Override
public void run() {
for(int i=0;i<3;i++){
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
}
System.out.println("////////");
}
}
運行結果:
可以看出:線程的狀態如下圖:
2.6 線程優先級
-
java提供了一個線程調度器來監控程序中啓動後進入就緒狀態的所有線程,線程調度器按照優先級決定應該調度那個線程來執行;
-
線程的優先級用數字表示,範圍1~10
-
Thread.MIN_PRIORITY=1;
-
Thread.MAX_PRIORITY=10;
-
使用一下方式改變或者獲取優先級:
-
getPriortity() setPrioritity(int xxx);
-
注意:優先級低只是意味着或得調度的概率低,並不是優先級低就不會被調用了;優先級高也不一定馬上就能獲取調度,這都是看cpu的調度;
-
優先級的設定建議在start()調用前;
-
默認的優先級是5。
/**
* 測試優先級
*/
public class TestPriority {
public static void main(String[] args) {
//主線程優先級
System.out.println(Thread.currentThread().getName()+":-->"+Thread.currentThread().getPriority());
MyPriority myPriority=new MyPriority();
Thread t0=new Thread(myPriority);
Thread t1=new Thread(myPriority);
Thread t2=new Thread(myPriority);
Thread t3=new Thread(myPriority);
Thread t4=new Thread(myPriority);
Thread t5=new Thread(myPriority);
t0.start();
//先設置優先級,在啓動
t1.setPriority(1);
t1.start();
t2.setPriority(4);
t2.start();
t3.setPriority(Thread.MAX_PRIORITY);//MAX_PRIORITY=10
t3.start();
t4.setPriority(8);
t4.start();
t5.setPriority(7);
t5.start();
}
}
class MyPriority implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+":-->"+Thread.currentThread().getPriority());
}
}
運行結果:
三、線程同步
請看:https://blog.csdn.net/qq_33157666/article/details/103949120