世界微尘里,吾宁爱与憎
如何用并发编程思想写一个排序算法
如何用并发编程思想写一个排序算法

如何用并发编程思想写一个排序算法

写代码(×)

整活(√)

灵感来源于B站up主-“IT楠老师”

首先,根据IT楠老师的思想,每遍历到一个数组中的数字的时候,就新建立一个线程,然后让这个线程休眠与数字大小相等的时间,休眠之后将这个数字输出,那么,数字比较小的就先结束休眠就会先行输出,而数字比较大的就会慢一步输出了,从而达到排序的效果

照着up主的方法写了一遍:

public static void sleepSort(int nums){
   for(int i=0;i<nums.length;i++){
       final int num = nums[i];
       new Thread(()->{
           try {
               Thread.sleep(num);
          } catch (InterruptedException e) {
               e.printStackTace();
          }
           System.out.println(num);
      }).start();
  }
}

但是,既然都是多线程并发排序算法了,竟然还在使用for循环遍历列表,这就显得很low

所以我决定使用了泛型列表List+forEach()来遍历这个列表

而且,我决定还要在forEach()中使用lambda表达式来显得算法更加高级(可惜不能用双冒号运算符)

而这样写的后果就是导致括号里面还嵌套了很多括号和大括号

最后写出来是这样的:

public class SortUtil {    
private static ReentrantLock lock = new ReentrantLock();
   private static Condition sufficientFunds = lock.newCondition();
   public static void main(String[] args) {
       Integer[] arr = {1, 7, 3, 9, 43, 45, 23, 18, 16, 33};
       sleepSort(arr);
  }    
public static void sleepSort(Integer[] arr) {
       List<Integer> list = Arrays.asList(arr);
       list.forEach(t->{
           new Thread(()-> {
               try {
                   Thread.sleep(t);
              } catch (InterruptedException e) {
                   e.printStackTrace();
              }
               System.out.println(t);
          }
          ).start();
              }
      );
  }
}

到了这一步,我觉得还是不够,既然是多线程,我们就要考虑线程带来的一些问题

比如说

Thread.sleep(t)这一段代码,对于每一个t,并不是在同一时间开始执行的,比如遍历到第十个t时,必须要等到第九个t进入休眠后才能执行第十个t的休眠操作,虽然这两个之间的时间间隔极端极端,但是如果数组长度变大,聚少成多,这种差异就无法忽略了(滑稽)

所以我们要做的,就是尽量减少这种差异

所以,我的思路是,每遍历到一个新的t时,就检测这个t是不是List的最后一位,如果不是,就让线程进入等待状态,直到遍历到List最后一位的时候,就让所有线程恢复,同时开始休眠

这样的话,是不是就免去了遍历数组带来的时间差异(maybe,其实我也不太确定)

所以我给这段代码增加了锁和条件对象的机制

public class SortUtil {
   private static ReentrantLock lock = new ReentrantLock();
   private static Condition sufficientFunds = lock.newCondition();
   public static void main(String[] args) {
       Integer[] arr = {1, 7, 3, 9, 43, 45, 23, 18, 16, 33};
       sleepSort(arr);
  }

   public static void sleepSort(Integer[] arr) {
       List<Integer> list = Arrays.asList(arr);
       list.forEach(t->{
           new Thread(()-> {
               try {
                   lock.lock();
                   int i = 0;
                   while(i == 0 && t != arr[arr.length - 1]) {
                       i++;
                       System.out.println("等待遍历");
                       sufficientFunds.await();
                  }
                   sufficientFunds.signalAll();
                   System.out.println("开始排序");
                   lock.unlock();
                   Thread.sleep(t);
              } catch (InterruptedException e) {
                   e.printStackTrace();
              }
               System.out.println(t);
          }
          ).start();
              }
      );
  }
}

好像和一般的多线程使用方法不一样呢……

这样写,我也不知道到底有没有用,也不知道到底这样写符不符合规范

但是代码是能跑而且正确输出的(艹),毕竟程序和人能跑一个就对了

测试一下

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注