Java 學習筆記 線程控制
阿新 • • 發佈:2019-04-12
不知道 package start return 關鍵字 bug creat 沒有 stat
題目一
本質上來說,線程是不可控制的,線程的執行是由CPU資源分配決定的,我們無法幹預系統CPU的資源分配,但我們可以增加條件來讓線程按照我們的預想順序來執行。
比如。如果當前的執行的線程不滿足我們所定的條件,那麽就讓CPU重新進行資源的分配,直到資源分配給我們所需要的某個線程
題目說明
編寫一個線程類(只有一個類),創建三個線程實例:A線程對象、B線程對象、C線程對象;A線程完成打印“A”, B線程完成打印“B”, C線程完成打印“C”;按照ABC,ABC,ABC……這樣來輸出。
思路
創建一個存放char的類,以線程名和char的數值為條件,從而控制指定的線程執行
如果單單只靠線程名,不能保證第一次運行的線程是A,線程調用start方法只是進入到就緒狀態,需要獲得CPU資源才能執行
代碼
MyChar.java
package HomeWork2; /** * @author StarsOne * @date Create in 2019-4-9 0009 19:53:39 * @description */ class MyChar { private char c = 'A'; public MyChar() { } public char getC() { return c; } public void setC(char c) { this.c = c; } }
PrintThread.java
package HomeWork2; /** * @author StarsOne * @date Create in 2019-4-9 0009 19:53:27 * @description */ class PrintThread extends Thread { private MyChar myChar ; public PrintThread(String name, MyChar myChar) { super(name); this.myChar = myChar; setDaemon(true);//設置為守護進程,主線程停止,當前的子線程也停止 } @Override public void run() { while (true) { synchronized (myChar) { if (getName().charAt(0) == 'A' && myChar.getC() == 'A') { System.out.print("A"); myChar.setC('B');//修改mychar裏面值,使得線程按指定順序執行 }else if (getName().charAt(0) == 'B' && myChar.getC() == 'B'){ System.out.print("B"); myChar.setC('C'); }else if (getName().charAt(0) == 'C' && myChar.getC() == 'C'){ System.out.print("C,"); myChar.setC('A'); } } try { sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } } } public static void main(String[] args) { MyChar myChar = new MyChar(); //註意這裏,某個線程傳入的都是同一個對象mychar new PrintThread("A", myChar).start(); new PrintThread("C", myChar).start(); new PrintThread("B", myChar).start(); //主線程休眠 try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } }
題目二
題目說明
3.寫兩個線程,一個線程打印1~52,另一個線程打印A~Z,打印順序是12A34B...5152Z;
思路
- 兩個線程,
NumberPrintThread
和CharPrintThread
,前者打印數字,後者打印字符
- 需要一個CharFlag類,其中有個flag標誌,標誌接下來要打印數字還是字符
CharFlag.java
package HomeWork3;
/**
* @author StarsOne
* @date Create in 2019-4-9 0009 20:37:49
* @description
*/
class CharFlag {
private boolean flag = false;//默認為false,因為先輸出數字
public boolean isFlag() {
return flag;
}
public synchronized void changeFlag() {
this.flag = !flag;
}
}
CharPrintThread.java
package HomeWork3;
/**
* @author StarsOne
* @date Create in 2019-4-9 0009 20:37:09
* @description
*/
class CharPrintThread extends Thread {
private CharFlag charFlag;
public CharPrintThread(CharFlag charFlag) {
this.charFlag = charFlag;
}
private char c = 'A';
@Override
public void run() {
while (c <= 'Z') {
if (charFlag.isFlag()) {
System.out.print(c+" ");//為了好看,加了個空格
charFlag.changeFlag();
c++;//註意這個遞增的位置
}
}
try {
sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
NumberPrintThread.java
package HomeWork3;
/**
* @author StarsOne
* @date Create in 2019-4-9 0009 20:37:09
* @description
*/
class NumberPrintThread extends Thread {
private int num =1;
private CharFlag charFlag;
public NumberPrintThread(CharFlag charFlag) {
this.charFlag = charFlag;
}
@Override
public void run() {
//num到52結束輸出
while (num<=52) {
if (!charFlag.isFlag()) {
System.out.print(num);
if (num % 2 == 0) {
charFlag.changeFlag();
}
num++;//註意這個遞增的位置
}
}
try {
sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Test.java
package HomeWork3;
/**
* @author StarsOne
* @date Create in 2019-4-9 0009 20:45:14
* @description
*/
class Test {
public static void main(String[] args) {
final CharFlag charFlag = new CharFlag();
new CharPrintThread(charFlag).start();
new NumberPrintThread(charFlag).start();
}
}
PS:不知道出現了什麽bug,多次運行後會輸出一部分之後就沒有輸出了,但是程序仍然在執行,似乎是死鎖問題?
上面的代碼中,出現了死鎖問題,因為sleep方法放在了while循環的外頭,兩個while循環,都會對flag就行修改,獲取的方法不是使用同步關鍵字修飾,所以就會造成死鎖問題
解決方法:
----
把sleep方法放在while循環中,或者把getFlag方法用同步關鍵字修飾
Java 學習筆記 線程控制