两个线程,顺序打印从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();
				}
			}
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值