`
javaG
  • 浏览: 550442 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

java线程测试

阅读更多

测试解决的问题:

线程的上下文切换真的很耗时么,耗时的话到底耗时到什么程度。

测试的机器是4核cpu,处理同样多的任务,看看耗时情况。

代码如下:

    private static void testContextSwitch()
    {
        AtomicInteger count = new AtomicInteger(0);
        long totolLoopNum = 1000000000;
        int threadNum = 1000;
        long loopNum = totolLoopNum/threadNum;
        System.out.println("totolLoopNum:"+totolLoopNum);
        System.out.println("threadNum:"+threadNum+"\tloopNum:"+loopNum);
        ExecutorService e = Executors.newFixedThreadPool(threadNum);
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < threadNum; i++)
        {
            e.execute(createLoopRunnable(count, loopNum, threadNum, startTime));
        }

    }

    private static Runnable createLoopRunnable(final AtomicInteger count, final long loopNum, final int threadNum,
            final long startTime)
    {
        return new Runnable()
        {

            @Override
            public void run()
            {
                for (int j = 0; j < 100; j++)
                {
                    int i = 0;
                    while (true)
                    {
                        if (i > loopNum)
                            break;
                        i++;
                    }
                }  
                int total = count.incrementAndGet();
                if (total == threadNum)
                    System.out.println("cost:" + (System.currentTimeMillis() - startTime));
            }
        };
    }

 

输出结果如下:

//    	totolLoopNum:1000000000
//    	threadNum:1	loopNum:1000000000
//    	cost:127198 cpu使用20%-40%
    	
//    	totolLoopNum:1000000000
//    	threadNum:2	loopNum:500000000
//    	cost:67120 cpu使用50%
    	
//    	totolLoopNum:1000000000
//    	threadNum:4	loopNum:250000000
//    	cost:36015 cpu使用100%
    	
//    	totolLoopNum:1000000000
//    	threadNum:64	loopNum:15625000
//    	cost:35905 cpu使用100%
    	
//    	totolLoopNum:1000000000
//    	threadNum:512	loopNum:1953125
//    	cost:35905

//    	totolLoopNum:1000000000
//    	threadNum:1000	loopNum:1000000
//    	cost:35955

 

可以看出:

1.在线程小于4的情况下cpu是不能跑到100%的。

2.随着线程数目的增加,处理任务的耗时越来越短,知道开到1000个线程的时候才开始有微弱的增加。

可以看出线程的上下文切换貌似不是很耗时。。。

 

实际应用中,比如阻塞读数据。经常会写如下类似代码:

//socket连接没有中断,阻塞读数据
while(socket != null)
{
 //阻塞的读写数据
}

代码1:

				while (true) {
					// 阻塞的读写数据
					try {
						if (queue.size() != 0) {
							System.out.println(1);
							// read;
						}
					} catch (Exception e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}

 代码2:

 

                                while (true) {
					// 阻塞的读写数据
					try {
						if (queue.take() != null) {
							System.out.println(1);
							// read;
						}
					} catch (Exception e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
 

  加入几个阻塞线程到线程池中发现,代码2加入后消耗的实践较少,代码1加入后消耗的实践较多。

通过jstack分析发现:

代码2中的线程处于WAITING状态,而代码1所有线程都是RUNNABLE。

java.util.concurrent.locks.LockSupport

http://forums.sun.com/thread.jspa?threadID=5353864

 

"pool-1-thread-3" prio=6 tid=0x01a0f800 nid=0x1fc4 waiting on condition [0x0c07f000..0x0c07fbe8]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x03ae66f0> (a java.util.concurrent.SynchronousQueue$TransferStack)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:158)
        at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:422)
        at java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:323)
        at java.util.concurrent.SynchronousQueue.take(SynchronousQueue.java:857)
        at lsd.Main$2.run(Main.java:205)
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
        at java.lang.Thread.run(Thread.java:619)
分享到:
评论
2 楼 alosin 2012-05-07  
我也是,用了java自带线程池后很多空闲的线程,最后导致不能创建新的线程了,线程池不是要重用么
1 楼 wuche 2011-07-03  
线程很多这个状态,有问题吗?我在一个项目中也遇到了这个问题,一共206个线程,有196个是这个状态
"pool-1-thread-3" prio=6 tid=0x01a0f800 nid=0x1fc4 waiting on condition [0x0c07f000..0x0c07fbe8] 
   java.lang.Thread.State: WAITING (parking) 
        at sun.misc.Unsafe.park(Native Method) 
        - parking to wait for  <0x03ae66f0> (a java.util.concurrent.SynchronousQueue$TransferStack) 



欢迎加我MSN聊聊,huiquanhuang@hotmail.com

相关推荐

Global site tag (gtag.js) - Google Analytics