【操作系统&数据结构图论】用有向图临接矩阵获得满足该前驱关系的线程数组

输入:

  一个无环有向图的对接矩阵。假设该矩阵尺寸为n × n

输出:

  一个长度为n的Thread数组。保证这n个线程的run方法内部都会通过Thread.currentThread().getName()互斥地输出一遍自己的线程名。并且输出的顺序要满足有向图中的前驱关系。run方法中的其它代码可以任意顺序执行。

  假设这个算法的名称是func(),表示有向图的对接矩阵是matrix,那么main函数中的内容是:

    public static Thread[] func(boolean[][] matrix) {
		/* code*/
	}
	
	public static void main(String[] args) {
		
		boolean[][] matrix = new matrix[][]{
			/* matrix */
		}
		
		Thread[] threads = func(matrix);
		
		for (Thread thread : threads) {
			thread.start();
		}
	
	}

样例:

输入样例1:

( 0 1 0 0 0 1 0 0 0 ) \left( \begin{matrix} 0 & 1 & 0 \\ 0 & 0 & 1 \\ 0 & 0 & 0 \end{matrix} \right) 000100010
有向图

输出样例1:
Thread-0
Thread-1
Thread-2
输入样例2:

( 0 0 1 1 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 ) \left( \begin{matrix} 0 & 0 & 1 & 1 & 1 & 0 & 0\\ 0 & 0 & 1 & 0 & 0 & 0 & 0\\ 0 & 0 & 0 & 0 & 0 & 0 & 0\\ 0 & 0 & 0 & 0 & 0 & 0 & 0\\ 0 & 0 & 0 & 0 & 0 & 1 & 1\\ 0 & 0 & 0 & 0 & 0 & 0 & 1\\ 0 & 0 & 0 & 0 & 0 & 0 & 0 \end{matrix} \right) 0000000000000011000001000000100000000001000000110
有向图

输出样例2:
Thread-0
Thread-4
Thread-1
Thread-3
Thread-2
Thread-5
Thread-6
Thread-1
Thread-0
Thread-2
Thread-4
Thread-5
Thread-6
Thread-3

  由于多线程的异步性,main函数的输出结果可以有多种,但是必须满足有向图所表示的前驱关系,这就得保证返回的Thread的数组只能有一种输出结果了。

  如果在检验算法结果的时候发现像输入样例2这样明明可以又输出运行结果的输入样例多次运行后只有一种输出结果,那说明肯定是把多线程算法当成单线程算法来做了,不给予通过。

代码实现:

import java.util.concurrent.Semaphore;

public class Solution {

	static Semaphore[][] semaphores;

	public static Thread[] func(boolean[][] matrix) {
		semaphores = new Semaphore[matrix.length][matrix[0].length];
		for (int i = 0; i < matrix.length; i++) {
			for (int j = 0; j < matrix[0].length; j++) {
				if (matrix[i][j]) semaphores[i][j] = new Semaphore(0);
			}
		}
		Thread[] threads = new Thread[matrix.length];
		for (int i = 0; i < threads.length; i++) {
			int j = i;
			threads[i] = new Thread(new Runnable() {
				@Override
				public void run() {
					try {
						for (int k = 0; k < semaphores.length; k++) {
							if (semaphores[k][j] != null) semaphores[k][j].acquire();
						}
						System.out.println(Thread.currentThread().getName());
						for (int k = 0; k < semaphores.length; k++) {
							if (semaphores[j][k] != null) semaphores[j][k].release();
						}
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			});
		}
		return threads;
	}

	public static void main(String[] args) {

		boolean[][] matrix = new boolean[][]{
				{false, false, true, true, true, false, false},
				{false, false, true, false, false, false, false},
				{false, false, false, false, false, false, false},
				{false, false, false, false, false, false, false},
				{false, false, false, false, false, true, true},
				{false, false, false, false, false, false, true},
				{false, false, false, false, false, false, false},
		};

		Thread[] threads = func(matrix);

		for (Thread thread : threads) {
			thread.start();
		}

	}

}

  运行结果:
运行结果一
运行结果二
运行结果三

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

九死九歌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值