`
shuofenglxy
  • 浏览: 190729 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

并发程序入门

阅读更多
多线程是改进顺序执行任务的利器之一。但多线程的使用,却带来这样那样的问题。先认识一下多线程。多线程就是利用多个最少执行单元在较短的时间内利用多核处理器近乎同时的执行同一个任务的不同部分,或者是不同任务。使得原来需要串行执行的任务能够并发的执行。这样的好处在于,缩短了这次任务的执行时间,给用户更好的响应。但多线程却未必会带来性能上的提高,因为多线程要考虑到多个线程的创建成本,多线程之间的上下文切换和挂起等消耗,甚至要考虑到共享资源的争夺消耗等,这些都为多线程使用增加了门槛。但多线程的提高任务执行时间的特点使得多线程的使用成为了必须。

先通过一个例子粗略的认识一下多线程的这个优点哈。

对一个拥有30个集合的任务进行排序操作。如果利用单任务的话,那么就是一个集合一个集合的顺序排序,最终排序完成就算任务完成。具体实例代码如下:
package multiThreadShow;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class NomalSeqTaskShow {

	@SuppressWarnings("unchecked")
	public static void main(String[] args){
		
		HashMap<Integer, ArrayList<Integer>>  map = new HashMap<Integer,ArrayList<Integer>>(); 
	
		for(int i=0;i<50;i++){
			ArrayList<Integer> arrayList= new ArrayList<Integer>(); 
			for(int i1=0;i1<10000;i1++){
				int p = (int) (Math.random()*10000);
				arrayList.add(p);
			}
			map.put(i, arrayList);
		}
		long start = System.currentTimeMillis();
		for(int i : map.keySet()){
			 Collections.sort(map.get(i));
		}
		long end = System.currentTimeMillis();	
		
		System.out.println("Excuting this totally costs "+(end - start));
	}
}


执行时间如下:
Excuting this totally costs 178


当通过简单的并发处理之后,执行的时间总时间就以最后完成的那个线程完成排序的时间为止了。这样的话,虽然有可能其中有些排序完成的消耗时间大于单线程执行消耗的时间,但是总时间却有可能减少。 具体代码如下:
package multiThreadShow;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.concurrent.CountDownLatch;

public class MultiThreadShow {

public static void main(String[] args){
		
		HashMap<Integer, ArrayList<Integer>>  map = new HashMap<Integer,ArrayList<Integer>>(); 
	
		for(int i=0;i<50;i++){
			ArrayList<Integer> arrayList= new ArrayList<Integer>(); 
			for(int i1=0;i1<10000;i1++){
				int p = (int) (Math.random()*10000);
				arrayList.add(p);
			}
			map.put(i, arrayList);
		}
		CountDownLatch doneSignal = new CountDownLatch(map.size());

		long start = System.currentTimeMillis();
		for(int i : map.keySet()){
			 SortThread t= new SortThread(doneSignal,"SortThread"+i);
			 t.setArrayList(map.get(i));
			 t.start();
		}
		
		try {
			doneSignal.await();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		long end = System.currentTimeMillis();	
		
		System.out.println("Excuting this totally costs "+(end - start));
	}
}

class SortThread extends Thread{
	private  ArrayList<Integer> arrayList;
	private final CountDownLatch doneSignal;

	public ArrayList<Integer> getArrayList() {
		return arrayList;
	}

	public void setArrayList(ArrayList<Integer> arrayList) {
		this.arrayList = arrayList;
	}

	public SortThread(CountDownLatch doneSignal,String name){
		super(name);
		this.doneSignal = doneSignal;
	}
	
	public void run(){
		Collections.sort(arrayList);
		doneSignal.countDown();
		//System.out.println("Sort finished"+this.getName());
	}
	
}


执行消耗时间如下:
Excuting this totally costs 118


结果可以看到,多线程使用合适的话,对提高任务的执行效率还有很有帮助了。这也是本文开始研究并发程序设计的初衷了。


分享到:
评论
3 楼 酒杯中的大海 2011-03-03  
shuofenglxy 写道
酒杯中的大海 写道
lz为什么多线程会快,是因为你的机器是双核的,如果是单核的,绝对是单线程的快!~(没测试过,但是差不多)

额  你这么理解也是正确的。
多线程与单线程的区别再去,多线程用了更多的硬件资源cpu 内存等来并发的完成一些列相互独立的子任务。要点在于控制合适的并发线程数目,从而充分高效的利用硬件资源,线程并不是越多越好,因为越多的线程意味着越多的线程上下文切换,这个代价某种条件下也是惊人的。

这样说就是正确的!~
2 楼 shuofenglxy 2011-03-02  
酒杯中的大海 写道
lz为什么多线程会快,是因为你的机器是双核的,如果是单核的,绝对是单线程的快!~(没测试过,但是差不多)

额  你这么理解也是正确的。
多线程与单线程的区别再去,多线程用了更多的硬件资源cpu 内存等来并发的完成一些列相互独立的子任务。要点在于控制合适的并发线程数目,从而充分高效的利用硬件资源,线程并不是越多越好,因为越多的线程意味着越多的线程上下文切换,这个代价某种条件下也是惊人的。
1 楼 酒杯中的大海 2011-03-02  
lz为什么多线程会快,是因为你的机器是双核的,如果是单核的,绝对是单线程的快!~(没测试过,但是差不多)

相关推荐

Global site tag (gtag.js) - Google Analytics