本文由西安白癜风专科医院收集,转载请注明出处本文由西安白癜风专科医院收集,转载请注明出处java多线程总结(一)java中的多线程在java中要想实现多线程,有两种手段,一种是继续Thread类,另外一种是实现Runable接口。对于直接继承Thread的类来说,代码大致框架是:[java]viewplaincopy1.class类名extendsThread{2.方法1;3.方法2;4.…5.publicvoidrun(){6.//othercode…7.}8.属性1;9.属性2;10.…11.12.}先看一个简单的例子:[java]viewplaincopy1./**2.*@authorRollen-Holt继承Thread类,直接调用run方法3.**/4.classhelloextendsThread{5.6.publichello(){7.8.}9.10.publichello(Stringname){11.this.name=name;12.}13.14.publicvoidrun(){15.for(inti=0;i5;i++){16.System.out.println(name+运行+i);17.}18.}19.本文由西安白癜风专科医院收集,转载请注明出处本文由西安白癜风专科医院收集,转载请注明出处20.publicstaticvoidmain(String[]args){21.helloh1=newhello(A);22.helloh2=newhello(B);23.h1.run();24.h2.run();25.}26.27.privateStringname;28.}【运行结果】:A运行0A运行1A运行2A运行3A运行4B运行0B运行1B运行2B运行3B运行4我们会发现这些都是顺序执行的,说明我们的调用方法不对,应该调用的是start()方法。当我们把上面的主函数修改为如下所示的时候:[java]viewplaincopy1.publicstaticvoidmain(String[]args){2.helloh1=newhello(A);3.helloh2=newhello(B);4.h1.start();5.h2.start();6.}然后运行程序,输出的可能的结果如下:A运行0B运行0B运行1B运行2B运行3本文由西安白癜风专科医院收集,转载请注明出处本文由西安白癜风专科医院收集,转载请注明出处B运行4A运行1A运行2A运行3A运行4因为需要用到CPU的资源,所以每次的运行结果基本是都不一样的,呵呵。注意:虽然我们在这里调用的是start()方法,但是实际上调用的还是run()方法的主体。那么:为什么我们不能直接调用run()方法呢?我的理解是:线程的运行需要本地操作系统的支持。如果你查看start的源代码的时候,会发现:[java]viewplaincopy1.publicsynchronizedvoidstart(){2./**3.*Thismethodisnotinvokedforthemainmethodthreadorsystem4.*groupthreadscreated/setupbytheVM.Anynewfunctionalityadded5.*tothismethodinthefuturemayhavetoalsobeaddedtotheVM.6.*7.*AzerostatusvaluecorrespondstostateNEW.8.*/9.if(threadStatus!=0||this!=me)10.thrownewIllegalThreadStateException();11.group.add(this);12.start0();13.if(stopBeforeStart){14.stop0(throwableFromStop);15.}16.}17.privatenativevoidstart0();注意我用红色加粗的那一条语句,说明此处调用的是start0()。并且这个这个方法用了native关键字,次关键字表示调用本地操作系统的函数。因为多线程的实现需要本地操作系统的支持。但是start方法重复调用的话,会出现java.lang.IllegalThreadStateException异常。通过实现Runnable接口:大致框架是:[java]viewplaincopy本文由西安白癜风专科医院收集,转载请注明出处本文由西安白癜风专科医院收集,转载请注明出处1.class类名implementsRunnable{2.方法1;3.方法2;4.…5.publicvoidrun(){6.//othercode…7.}8.属性1;9.属性2;10.…11.12.}来先看一个小例子吧:[java]viewplaincopy1./**2.*@authorRollen-Holt实现Runnable接口3.**/4.classhelloimplementsRunnable{5.6.publichello(){7.8.}9.10.publichello(Stringname){11.this.name=name;12.}13.14.publicvoidrun(){15.for(inti=0;i5;i++){16.System.out.println(name+运行+i);17.}18.}19.20.publicstaticvoidmain(String[]args){21.helloh1=newhello(线程A);22.Threaddemo=newThread(h1);23.helloh2=newhello(线程B);24.Threaddemo1=newThread(h2);25.demo.start();26.demo1.start();27.}本文由西安白癜风专科医院收集,转载请注明出处本文由西安白癜风专科医院收集,转载请注明出处28.29.privateStringname;30.}【可能的运行结果】:线程A运行0线程B运行0线程B运行1线程B运行2线程B运行3线程B运行4线程A运行1线程A运行2线程A运行3线程A运行4关于选择继承Thread还是实现Runnable接口?其实Thread也是实现Runnable接口的:[java]viewplaincopy1.classThreadimplementsRunnable{2.//…3.publicvoidrun(){4.if(target!=null){5.target.run();6.}7.}8.}其实Thread中的run方法调用的是Runnable接口的run方法。不知道大家发现没有,Thread和Runnable都实现了run方法,这种操作模式其实就是代理模式。Thread和Runnable的区别:如果一个类继承Thread,则不适合资源共享。但是如果实现了Runable接口的话,则很容易的实现资源共享。[java]viewplaincopy1./**本文由西安白癜风专科医院收集,转载请注明出处本文由西安白癜风专科医院收集,转载请注明出处2.*@authorRollen-Holt继承Thread类,不能资源共享3.**/4.classhelloextendsThread{5.publicvoidrun(){6.for(inti=0;i7;i++){7.if(count0){8.System.out.println(count=+count--);9.}10.}11.}12.13.publicstaticvoidmain(String[]args){14.helloh1=newhello();15.helloh2=newhello();16.helloh3=newhello();17.h1.start();18.h2.start();19.h3.start();20.}21.22.privateintcount=5;23.}【运行结果】:count=5count=4count=3count=2count=1count=5count=4count=3count=2count=1count=5count=4count=3count=2count=1本文由西安白癜风专科医院收集,转载请注明出处本文由西安白癜风专科医院收集,转载请注明出处大家可以想象,如果这个是一个买票系统的话,如果count表示的是车票的数量的话,说明并没有实现资源的共享。我们换为Runnable接口:[java]viewplaincopy1./**2.*@authorRollen-Holt继承Thread类,不能资源共享3.**/4.classhelloimplementsRunnable{5.publicvoidrun(){6.for(inti=0;i7;i++){7.if(count0){8.System.out.println(count=+count--);9.}10.}11.}12.13.publicstaticvoidmain(String[]args){14.hellohe=newhello();15.newThread(he).start();16.}17.18.privateintcount=5;19.}【运行结果】:count=5count=4count=3count=2count=1总结一下吧:实现Runnable接口比继承Thread类所具有的优势:1):适合多个相同的程序代码的线程去处理同一个资源2):可以避免java中的单继承的限制3):增加程序的健壮性,代码可以被多个线程共享,代码和数据独立。所以,本人建议大家劲量实现接口。[java]viewplaincopy本文由西安白癜风专科医院收集,转载请注明出处本文由西安白癜风专科医院收集,转载请注明出处1./**2.*@authorRollen-Holt3.*取得线程的名称4.**/5.classhelloimplementsRunnable{6.publicvoidrun(){7.for(inti=0;i3;i++){8.System.out.println(Thread.currentThread().getName());9.}10.}11.12.publicstaticvoidmain(String[]args){13.hellohe=newhello();14.newThread(he,A).start();15.newThread(he,B).start();16.newThread(he).start();17.}18.}【运行结果】:AAABBBThread-0Thread-0Thread-0说明如果我们没有指定名字的话,系统自动提供名字。提醒一下大家:main方法其实也是一个线程。在java中所以的线程都是同时启动的,至于什么时候,哪个先执行,完全看谁先得到CPU的资源。在java中,每次程序运行至少启动2个线程。一个是main线程,一个是垃圾收集线程。因为每当使用java命令执行一个