多线程编程在实际项目中的运用

最近在实际项目中遇到了需要多线程来处理的一个实际问题:一堆视频资源需要上传到一个cc平台,如果串行处理,显然不能很好实用多核的cpu处理器,于是考虑到实用线程的方式进行上传,但是创建多少个线程了?如果一个资源对应一个线程去处理,当资源数目过多的时候,创建的线程过多,同时执行处理资源显然会把服务器搞崩。经过思考,和同事进行讨论,也是同事的提醒,建议说一次性最多创建5个线程,进行对资源进行处理比较好,创建5个线程,然后这个5个线程同时去抢资源,抢到一个资源然后在进行处理,于是有了下面落地的方案:

1.线程安全的集合存放资源

  • ArrayList :
  • LinkedList:
  • HashMap:
  • HashSet:
  • TreeMap:
  • TreeSet:
  • StringBulider:
以上都是线程不安全的,最后选择使用ConcurrentLinkedQueue,它是线程安全的集合, 允许并发的访问数据结构的不同部分来使竞争极小化。 这些集合返回弱一致性的迭代器。这意味着迭代器不一定能反映出他们被构造之后的所有的修改,但是,他们不会将同一个值返回两次。

2.多线程代码编写

[html]  view plain  copy
  1. package com.lgy;  
  2.   
  3. import java.util.Queue;  
  4. import java.util.concurrent.ConcurrentLinkedQueue;  
  5.   
  6. /**  
  7.  * Created by fengch on 2018/3/8.  
  8.  */  
  9. public class MyTest {  
  10.   
  11.     public static void main(String[] args) {  
  12.         final Queue<String> queue = new ConcurrentLinkedQueue<String>();  
  13.         queue.add("11111111111");  
  14.         queue.add("22222222222");  
  15.         queue.add("33333333333");  
  16.         queue.add("44444444444444");  
  17.         queue.add("555555555555555");  
  18.         queue.add("666666666666666");  
  19.         queue.add("7777777777777");  
  20.   
  21.   
  22.         for(int i = 0; i < 5; i++) {  
  23.             new Thread(new Runnable() {  
  24.                 @Override  
  25.                 public void run() {  
  26.                     while (queue.size() > 0) {  
  27.                         try {  
  28.                             Thread.sleep(1000);  
  29.                         } catch (InterruptedException e) {  
  30.                             e.printStackTrace();  
  31.                         }  
  32.                         String value = queue.poll();  
  33.                         if(value != "" && null != value)  
  34.                             System.out.println(Thread.currentThread().getName() + "------------ " + value);  
  35.                     }  
  36.   
  37.   
  38.                 }  
  39.             }).start();  
  40.         }  
  41.     }  
  42. }这种写法,既不会出现漏掉资源的情况,同时也不会出现将同一个资源同时执行的情况!  

ps,如何判断创建的所以线程都执行完毕了呢?

[html]  view plain  copy
  1. ExecutorService exec = Executors.newCachedThreadPool();  
  2. final CountDownLatch endGate = new CountDownLatch(5);  
这两种方式都可以实现,一种是将所以的线程放在一个线程池中,另一种是使用闭锁的方式,计数器,当计数器为0的时候,表示所以的线程都已经执行完成!

猜你喜欢

转载自blog.csdn.net/qq_34107571/article/details/80063065