机器学习和生物信息学实验室联盟

标题: 关于java多线程的一些问题 [打印本页]

作者: hsc    时间: 2011-7-30 14:53
标题: 关于java多线程的一些问题
对于java来说,掌握基本语言已经够呛,在使用到多线程等技术的时候,往往让人望而却步,搞了一个程序,使用多线程,其实程序并不多,但是就是学习多线程的技术就搞了一个晚上,实际上创建多线程以及运用也不是很难,当然我说的是基本应用,如果牵涉到比较深入的部分,那就请自己参考相关技术吧,我把我这程序里使用到的多线程部分给大家8一下。
首先我这个程序是处理一个大的文件,大概200多M,如果单线程的话需要600多秒,四线程的话只需要240秒。我把那一段代码粘贴上解释一下吧。
Thread[] thread=new Thread[threadNum];//创建多线程
for(int i=0;i<threadNum;++i)//分配线程体
{
        thread[i]=new SolveWay(i+"");
        thread[i].start();//启动进程
}
这个是在主方法里的程序,如果想用几个线程就创建几个线程体,其中SolveWay是主类继承了Thread,当然也可以利用接口实现,SolveWay()里的参数是标示的进程的名字。然后在本类构造函数里用super()对线程名字赋值。
public void run()
{
        try {
                int num=Integer.parseInt(this.getName());//获取进程的名字
                Flow f=new Flow("test_temportary_data"+num+".txt","temportary_data"+num+".arff","?");
                f.run();
                count++;
                if(count==threadCount)
                {
                        maketest(4);
                        voteresult vr=new voteresult("","test.arff",4);
                        vr.run();
                        timeEnd=System.currentTimeMillis();
                        System.out.println("耗时:"+(timeEnd-timeStart));
                }
        } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
        }
}
线程运行的过程就是在run()方法里,当线程start()之后,进程自动调用run()方法执行,这里有一个小问题,就是线程的执行没有先后之别,是并行执行的,你怎么知道所有的线程都执行完了呢,我不知道别人用什么方法,没有仔细查,我使用的一个方法是,定义一个全局变量,用来记录有多少个线程执行完毕,就是上面程序中的count,如果count等于所有的进程数threadCount的话,标示所有的进程全部执行完毕,就可以写后续程序了。注意:后续程序不能写在主方法里调用进程的后边,因为程序在执行的过程中会首先执行main方法也就是主进程,那么子进程还没有执行完毕,主进程和子进程全部都是并行执行的。对于上面的程序只是参考,至于到时候写什么内容,根据自己而定,框架是可以复制,内容完全可以更换。

以上是我对使用多线程的一点小小的心得体会,希望以后对大家有所帮助,如果大家对多线程有更好的看法的话,可以在论坛上发出来,以供参考,如果觉的我的那个地方用得不对的话,也可以提出来,谢谢~
作者: zouquan    时间: 2011-7-30 15:30
very gooooooooooooood

我不懂多线程,有没有懂的大牛出来点评一下?

那种顺序处理fasta序列,以后可以用多线程提高速度;另外blast有一个参数-a,可以人为设定使用cpu个数,我怀疑是不是就是人为设定线程个数?
作者: hsc    时间: 2011-7-30 15:35
按道理说应该是的,虽然在程序里创建的多线程在占用CPU上不能专一,但是大致上差不多,我想应该是可以在程序里进行设置的,只不过暂时还不能搞定~:P
另外,我把实验所使用的时间和线程对比结果贴出来,以供大家参考一下:
使用1个线程时间:620078ms 四个CPU都有所使用,运行到中间阶段,基本保持两个半CPU,其他两个很少

使用2个线程时间:357562ms 使用1个满CPU,两个半CPU

使用3个线程时间:283969ms 使用2个满CPU,两个半CPU

使用4个线程时间:249438ms 使用4个CPU

使用8个线程时间:311578ms 四个CPU全部占满

使用16个线程时间:356797ms 四个CPU全部占满
作者: xmubingo    时间: 2011-8-12 10:35
咦,很不错的效果。我也想研究研究,“number of processors”这个参数blast是怎么实现的
作者: xmubingo    时间: 2011-8-12 11:09
blast里面的CPU核数应该就是线程数...
作者: hsc    时间: 2011-8-14 12:46
xmubingo 发表于 2011-8-12 11:09
blast里面的CPU核数应该就是线程数...

有点高深了~~~
作者: xmubingo    时间: 2011-8-14 13:22
我认为设置线程数和利用到的CPU核数是不同概念的。

线程数是指这个进程带几个线程,对于进程而言。CPU核心数是对CPU而言。两者通过操作系统调度实现合理配置。

首先,多线程能实现并发从而提高效率要建立在CPU支持多线程的基础上,这个现在的多核CPU都能支持。

其次,一个进程即使有多个线程,能利用到几个CPU核心是由操作系统支配的。操作系统决定了哪个线程在哪个核心上跑。如果是4个CPU核心,4个线程,在资源分配充足的情况下,每个核心跑一个线程是OS的最优调度。但是,如果,在资源紧张,例如,其他三个核心已经被其他进程高负荷占据,这个时候即使你有4个线程,也被放在一个CPU核心上,这种情况并不能实现并发从而提高效率,因为4个线程不断切换会产生巨大的代价(某核心在某一时刻只能跑其中的一个线程)。

最后,多线程存在的风险是,只要一个进程中的一个线程出现错误终止,那么整个进程都会被终止。其他情况考虑,多线程毫无疑问是提高运行效率的良好手段。
作者: zouquan    时间: 2011-8-14 13:53
很好

特别是多线程的容错能力确实值得考虑,因此我们更应该去学习hadoop,我猜想在单机情况下,hadoop可以等价于多线程,但hadoop的容错能力要好于多线程。

我在想:如果用户机器中没有hadoop环境,我们把hadoop.jar打包入软件中,对方机器是否能执行。




欢迎光临 机器学习和生物信息学实验室联盟 (http://123.57.240.48/) Powered by Discuz! X3.2