需求描述
這裏考察對線程鎖的使用,多線程情況下如何控制各自的執行時間段。
解題思路
我想到的有兩種接替思路,一種是使用標誌位,一種是使用線程鎖。
使用標誌位的思路如下:
兩個線程一個打印偶數,一個打印奇數,兩個線程要交叉執行,所以可以用一個長度爲101的數組(第一個位置不用,便於打印的數字和位置保持一致)保存每個線程的執行狀態,一個線程執行完畢後在對應位置設置成1,之前前判斷數組中前一個位置是否爲1,不爲1則等待,流程如下:
- 初始化一個全局數組,長度爲101,並且每個線程使用num計數,本線程中需要使用的數組的位置,也是需要打印的數組。
- 先讓需要輸出奇數的線程打印一次,數組中狀態爲1,0,0,0…,同時num+2。
- 後續兩個線程在打印前都判斷數組中前一個位置(num-1)是否爲1,如果是1,則打印num,同時num+2;否則,等待另外一個線程。
使用線程鎖的思路如下:
這種方式就很簡單了,直接使用Lock就可以。初始化線程時在線程中設置一個標識,0代表打印偶數,1代表打印奇數。
定義一個全局變量num代表要打印的數字,在線程中判斷當前要打印的數字是不是和本線程一直,即奇數=奇數線程,偶數對應偶數線程,如果一直則打印,num++,同時喚醒另外的線程;否則進行等待。
代碼編寫
思路一
import java.util.concurrent.locks.LockSupport;
/**
* @Function
*
*
* @Update
*
* @Author cc
* @CreateTime 2020年03月04日
*/
public class Day2020304 {
public static void main(String[] args) throws Exception {
Day2020304 main = new Day2020304();
main.run();
}
int[] array = new int[101];
void run() throws Exception {
new Thread(new PrintThread(1)).start();
new Thread(new PrintThread(2)).start();
}
class PrintThread implements Runnable {
int id;
public PrintThread(int id) {
this.id = id;
}
public void run() {
int num = id;
if (id == 1) {
System.out.println("id " + id + " - " + num);
array[num] = 1;
num += 2;
}
while (num <= 100) {
while (array[num - 1] == 0) {
LockSupport.parkNanos(10);
}
System.out.println("id " + id + " - " + num);
array[num] = 1;
num += 2;
}
}
}
}
思路二
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* @Function
*
*
* @Update
*
* @Author cc
* @CreateTime 2020年03月04日
*/
public class Day2020304 {
public static void main(String[] args) throws Exception {
Day2020304 main = new Day2020304 ();
main.run();
}
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
int num = 1;
void run() throws Exception {
new Thread(new PrintThread(0)).start();
new Thread(new PrintThread(1)).start();
}
class PrintThread implements Runnable {
int id;
public PrintThread(int id) {
this.id = id;
}
public void run() {
while (num <= 100) {
lock.lock();
try {
if (num % 2 == id) {
System.out.println("id " + id + " - " + num);
num ++;
condition.signalAll();
} else {
condition.await();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
}
}