关于多线程应用之一
?????? 最近开始做了一个关于多线程的项目,这个项目是关于淘宝图片认证防伪项目,遇到的问题是大批图片认证上传业务,预计每天的流量是10g以上。大批图片我们不能进行单线程运作,否则问题就大了。理论是多线程技术,负载均衡技术,高速缓存技术可以解决这样的问题。想法是好的,问题就在技术方案和解决方案。
??????? 在jdk1.4以前没有concurrent包。提供的就是synchronized同步和wait,也没有线程池技术,但是在jdk5/6就不相同了。对于jdk1.4模拟实现:
public class TaskManagerQuene { private LinkedList<String> taskQuene = new LinkedList<String>(); public void addTask(String task) throws InterruptedException { synchronized (this.taskQuene) { while (this.taskQuene.size() == 10) { this.taskQuene.wait(); } this.taskQuene.add(task); this.taskQuene.notifyAll(); } } public String getTask() throws InterruptedException { synchronized (this.taskQuene) { String str = null; while(this.taskQuene.size()==0){ this.taskQuene.wait(); } str = this.taskQuene.remove(); this.taskQuene.notifyAll(); return str; } }}?这样的写法很糟糕,如果处理不当,很容易造成线程死锁,可读性也差。不能进行手工解锁,采用jdk5/6实现手法就不一样了,如下:
public class TaskManageQuene { private LinkedList<Runnable> taskUrlQuene; private LinkedList<Runnable> taskImageDownload; private Lock taskUrlLock = new ReentrantLock(); private Condition addTaskCondition = taskUrlLock.newCondition(); private Condition getTaskCondition = taskUrlLock.newCondition(); public TaskManageQuene() { this.taskUrlQuene = new LinkedList<Runnable>(); } public void addTask(Runnable task) { taskUrlLock.lock(); try { while (this.taskUrlQuene.size() == 10) { this.addTaskCondition.await(); } this.taskUrlQuene.add(task); this.getTaskCondition.signalAll(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { taskUrlLock.unlock(); } } public Runnable getTask() { taskUrlLock.lock(); Runnable run = null; try { while (this.taskUrlQuene.size() == 0) { this.getTaskCondition.await(); } run = this.taskUrlQuene.remove(); this.addTaskCondition.signalAll(); return run; } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { } return run; }}?注意:Condition对应wait,notify,这里我们随时都可以解锁,避免了线程死锁问题,这个线程的模式是
1.生产者-消费者2.生产者-消费者,第一消费者是第二个的生产者。
?
?
在jdk5/6提供了现成的线程池实现,
?
?
?
TaskProductExcutorPool taskProductExcutorPool = new TaskProductExcutorPool(taskQueue); TaskCustomerExecutorPool taskCustomerExecutorPool = new TaskCustomerExecutorPool(taskQueue); ExecutorService executorService = Executors.newFixedThreadPool(10); executorService.execute(taskCustomerExecutorPool); executorService.execute(taskProductExcutorPool); taskCustomerExecutorPool.shutDown(); taskProductExcutorPool.shutDown(); executorService.shutdown();?
?
?
?