兩個線程,順序打印從1-100的數字,一個線程打印奇數,一個線程打印偶數

需求描述

這裏考察對線程鎖的使用,多線程情況下如何控制各自的執行時間段。

解題思路

我想到的有兩種接替思路,一種是使用標誌位,一種是使用線程鎖。

使用標誌位的思路如下
兩個線程一個打印偶數,一個打印奇數,兩個線程要交叉執行,所以可以用一個長度爲101的數組(第一個位置不用,便於打印的數字和位置保持一致)保存每個線程的執行狀態,一個線程執行完畢後在對應位置設置成1,之前前判斷數組中前一個位置是否爲1,不爲1則等待,流程如下:

  1. 初始化一個全局數組,長度爲101,並且每個線程使用num計數,本線程中需要使用的數組的位置,也是需要打印的數組。
  2. 先讓需要輸出奇數的線程打印一次,數組中狀態爲1,0,0,0…,同時num+2。
  3. 後續兩個線程在打印前都判斷數組中前一個位置(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();
				}
			}
		}
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章