关于多线程应用之一

       最近开始做了一个关于多线程的项目,这个项目是关于淘宝图片认证防伪项目,遇到的问题是大批图片认证上传业务,预计每天的流量是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();
 

 

 

 

你可能感兴趣的:(多线程)