多线程实际开发中的使用

场景一:线程1执行完再执行线程2

@Test
public void test4() {
   try {
       Runnable runnable = () -> {
           try {
               System.out.println();
               for (int i = 0; i < 10; i++) {
                   System.out.println("线程1开始执行: " + Thread.currentThread().getName() + " " + i);
               }
           } catch (Exception e) {
               e.printStackTrace();
           }
       };
       Runnable runnable2 = () -> {
           try {
               for (int i = 0; i < 5; i++) {
                   System.out.println("线程2开始执行: " + Thread.currentThread().getName() + " " + i);
               }
           } catch (Exception e) {
               e.printStackTrace();
           }
       };
       Thread thread1 = new Thread(runnable);
       Thread thread2 = new Thread(runnable2);

       thread1.start();
       thread1.join();
       thread2.start();

   } catch (Exception e) {
       e.printStackTrace();
   }
}

场景二:线程的异步操作,线程1执行完 返回,线程2继续执行

@Test
public void testReturn() {
   doReturn("abc");
}

public String doReturn(String s) {
   try {
       Runnable runnable = () -> {
           try {
               System.out.println("执行11111111111");
               for (int i = 0; i < 100; i++) {
                   System.out.print(" " + i + " ");
               }
               return;
           } catch (Exception e) {
               e.printStackTrace();
           }
       };
       Runnable runnable2 = () -> {
           try {
               System.out.println("执行222222222");
               for (int i = 100; i < 200; i++) {
                   System.out.print(" " + i + " ");
               }
           } catch (Exception e) {
               e.printStackTrace();
           }
       };
       new Thread(runnable).start();
       new Thread(runnable2).start();

   } catch (Exception e) {
       e.printStackTrace();
   }
   return null;
}

场景三:使用线程池,处理数据(每N条数据开一个线程)

public static void main(String[] args) throws InterruptedException {
   List list = new ArrayList();
   list.add("111");
   list.add("222");
   list.add("333");
   list.add("444");
   list.add("555");
   list.add("666");
   list.add("777");
   list.add("888");
   list.add("999");
   // 多线程处理发短信
   // 开始时间
   long startSMSTime = System.currentTimeMillis();
   // 每3条数据开启一条线程
   int threadSize = 3;
   // 总数据条数
   int dataSize = list.size();
   // 线程数
   int threadNum = dataSize / threadSize + 1;
   // 定义标记,过滤threadNum为整数
   boolean special = dataSize % threadSize == 0;

   // 创建一个线程池
   ExecutorService exec = Executors.newFixedThreadPool(threadNum);
   // 定义一个任务集合
   List<Callable<Integer>> tasks = new ArrayList<>();
   Callable<Integer> task = null;
   List<String> cutList = null;

   // 确定每条线程的数据
   for (int j = 0; j < threadNum; j++) {
       if (j == threadNum - 1) {
           if (special) {
               break;
           }
           cutList = list.subList(threadSize * j, dataSize);
       } else {
           cutList = list.subList(threadSize * j, threadSize * (j + 1));
       }
       final List<String> listStr = cutList;
       task = () -> {
           listStr.forEach(phone -> {
               try {
                   if (!StringUtils.isEmpty(phone)) {
                       // 调用短信
                       System.out.println("执行发短信操作的线程是......" + Thread.currentThread().getName());
                   }
               } catch (Exception e) {
                   e.printStackTrace();
               }
           });
            System.out.println("当前线程任务列表:"+ listStr);
           return 1;
       };
       // 这里提交的任务容器列表和返回的Future列表存在顺序对应的关系
       tasks.add(task);
   }
   List<Future<Integer>> results = exec.invokeAll(tasks);
   // 关闭线程池
   exec.shutdown();
   System.out.println("线程任务执行结束");
   System.out.println("执行任务消耗了: " + (System.currentTimeMillis() - startSMSTime));
}


发表评论