java多线程学习经典教程Word文档格式.docx

上传人:b****2 文档编号:5726459 上传时间:2023-05-05 格式:DOCX 页数:44 大小:26.11KB
下载 相关 举报
java多线程学习经典教程Word文档格式.docx_第1页
第1页 / 共44页
java多线程学习经典教程Word文档格式.docx_第2页
第2页 / 共44页
java多线程学习经典教程Word文档格式.docx_第3页
第3页 / 共44页
java多线程学习经典教程Word文档格式.docx_第4页
第4页 / 共44页
java多线程学习经典教程Word文档格式.docx_第5页
第5页 / 共44页
java多线程学习经典教程Word文档格式.docx_第6页
第6页 / 共44页
java多线程学习经典教程Word文档格式.docx_第7页
第7页 / 共44页
java多线程学习经典教程Word文档格式.docx_第8页
第8页 / 共44页
java多线程学习经典教程Word文档格式.docx_第9页
第9页 / 共44页
java多线程学习经典教程Word文档格式.docx_第10页
第10页 / 共44页
java多线程学习经典教程Word文档格式.docx_第11页
第11页 / 共44页
java多线程学习经典教程Word文档格式.docx_第12页
第12页 / 共44页
java多线程学习经典教程Word文档格式.docx_第13页
第13页 / 共44页
java多线程学习经典教程Word文档格式.docx_第14页
第14页 / 共44页
java多线程学习经典教程Word文档格式.docx_第15页
第15页 / 共44页
java多线程学习经典教程Word文档格式.docx_第16页
第16页 / 共44页
java多线程学习经典教程Word文档格式.docx_第17页
第17页 / 共44页
java多线程学习经典教程Word文档格式.docx_第18页
第18页 / 共44页
java多线程学习经典教程Word文档格式.docx_第19页
第19页 / 共44页
java多线程学习经典教程Word文档格式.docx_第20页
第20页 / 共44页
亲,该文档总共44页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

java多线程学习经典教程Word文档格式.docx

《java多线程学习经典教程Word文档格式.docx》由会员分享,可在线阅读,更多相关《java多线程学习经典教程Word文档格式.docx(44页珍藏版)》请在冰点文库上搜索。

java多线程学习经典教程Word文档格式.docx

16

17

18

19

20

21

22

23

24

25

26

27

28

/**

*@authorRollen-Holt继承Thread类,直接调用run方法

**/

classhelloextendsThread{

publichello(){

}

publichello(Stringname){

this.name=name;

publicvoidrun(){

for(inti=0;

i<

5;

i++){

System.out.println(name+"

运行"

+i);

publicstaticvoidmain(String[]args){

helloh1=newhello("

A"

);

helloh2=newhello("

B"

h1.run();

h2.run();

privateStringname;

【运行结果】:

A运行0

A运行1

A运行2

A运行3

A运行4

B运行0

B运行1

B运行2

B运行3

B运行4

我们会发现这些都是顺序执行的,说明我们的调用方法不对,应该调用的是start()方法。

当我们把上面的主函数修改为如下所示的时候:

publicstaticvoidmain(String[]args){

h1.start();

h2.start();

然后运行程序,输出的可能的结果如下:

因为需要用到CPU的资源,所以每次的运行结果基本是都不一样的,呵呵。

注意:

虽然我们在这里调用的是start()方法,但是实际上调用的还是run()方法的主体。

那么:

为什么我们不能直接调用run()方法呢?

我的理解是:

线程的运行需要本地操作系统的支持。

如果你查看start的源代码的时候,会发现:

publicsynchronizedvoidstart(){

/**

*Thismethodisnotinvokedforthemainmethodthreador"

system"

*groupthreadscreated/setupbytheVM.Anynewfunctionalityadded

*tothismethodinthefuturemayhavetoalsobeaddedtotheVM.

*

*Azerostatusvaluecorrespondstostate"

NEW"

.

*/

if(threadStatus!

=0||this!

=me)

thrownewIllegalThreadStateException();

group.add(this);

start0();

if(stopBeforeStart){

stop0(throwableFromStop);

privatenativevoidstart0();

注意我用红色加粗的那一条语句,说明此处调用的是start0()。

并且这个这个方法用了native关键字,次关键字表示调用本地操作系统的函数。

因为多线程的实现需要本地操作系统的支持。

但是start方法重复调用的话,会出现java.lang.IllegalThreadStateException异常。

通过实现Runnable接口:

大致框架是:

class类名implementsRunnable{

来先看一个小例子吧:

29

30

*@authorRollen-Holt实现Runnable接口

classhelloimplementsRunnable{

线程A"

Threaddemo=newThread(h1);

线程B"

Threaddemo1=newThread(h2);

demo.start();

demo1.start();

【可能的运行结果】:

线程A运行0

线程B运行0

线程B运行1

线程B运行2

线程B运行3

线程B运行4

线程A运行1

线程A运行2

线程A运行3

线程A运行4

关于选择继承Thread还是实现Runnable接口?

其实Thread也是实现Runnable接口的:

classThreadimplementsRunnable{

//…

publicvoidrun(){

if(target!

=null){

target.run();

其实Thread中的run方法调用的是Runnable接口的run方法。

不知道大家发现没有,Thread和Runnable都实现了run方法,这种操作模式其实就是代理模式。

关于代理模式,我曾经写过一个小例子呵呵,大家有兴趣的话可以看一下:

Thread和Runnable的区别:

如果一个类继承Thread,则不适合资源共享。

但是如果实现了Runable接口的话,则很容易的实现资源共享。

*@authorRollen-Holt继承Thread类,不能资源共享

7;

if(count>

0){

System.out.println("

count="

+count--);

helloh1=newhello();

helloh2=newhello();

helloh3=newhello();

h3.start();

privateintcount=5;

count=5

count=4

count=3

count=2

count=1

大家可以想象,如果这个是一个买票系统的话,如果count表示的是车票的数量的话,说明并没有实现资源的共享。

我们换为Runnable接口

classMyThreadimplementsRunnable{

privateintticket=5;

//5张票

for(inti=0;

i<

=20;

if(this.ticket>

System.out.println(Thread.currentThread().getName()+"

正在卖票"

+this.ticket--);

publicclasslzwCode{

publicstaticvoidmain(String[]args){

MyThreadmy=newMyThread();

newThread(my,"

1号窗口"

).start();

2号窗口"

3号窗口"

  

总结一下吧:

实现Runnable接口比继承Thread类所具有的优势:

1):

适合多个相同的程序代码的线程去处理同一个资源

2):

可以避免java中的单继承的限制

3):

增加程序的健壮性,代码可以被多个线程共享,代码和数据独立。

所以,本人建议大家劲量实现接口。

*@authorRollen-Holt

*取得线程的名称

3;

System.out.println(Thread.currentThread().getName());

hellohe=newhello();

newThread(he,"

newThread(he).start();

A

B

Thread-0

说明如果我们没有指定名字的话,系统自动提供名字。

提醒一下大家:

main方法其实也是一个线程。

在java中所以的线程都是同时启动的,至于什么时候,哪个先执行,完全看谁先得到CPU的资源。

在java中,每次程序运行至少启动2个线程。

一个是main线程,一个是垃圾收集线程。

因为每当使用java命令执行一个类的时候,实际上都会启动一个JVM,每一个jVM实习在就是在操作系统中启动了一个进程。

判断线程是否启动

*@authorRollen-Holt判断线程是否启动

Threaddemo=newThread(he);

线程启动之前---》"

+demo.isAlive());

线程启动之后---》"

【运行结果】

线程启动之前---》false

线程启动之后---》true

主线程也有可能在子线程结束之前结束。

并且子线程不受影响,不会因为主线程的结束而结束。

线程的强制执行:

*@authorRollen-Holt线程的强制执行

classhelloimplementsRunnable{

Threaddemo=newThread(he,"

线程"

for(inti=0;

i<

50;

++i){

if(i>

10){

try{

demo.join();

//强制执行demo

}catch(Exceptione){

e.printStackTrace();

main线程执行-->

"

+i);

【运行的结果】:

线程

...

线程的休眠:

*@authorRollen-Holt线程的休眠

try{

Thread.sleep(2000);

System.out.println(Thread.currentThread().getName()+i);

(结果每隔2s输出一个)

线程0

线程1

线程2

线程的中断:

*@authorRollen-Holt线程的中断

执行run方法"

Thread.sleep(10000);

线程完成休眠"

休眠被打断"

return;

//返回到程序的调用处

线程正常终止"

demo.interrupt();

//2s后中断线程

执行run方法

休眠被打断

在java程序中,只要前台有一个线程在运行,整个java程序进程不会小时,所以此时可以设置一个后台线程,这样即使java进程小时了,此后台线程依然能够继续运行。

*@authorRollen-Holt后台线程

while(true){

System.out.println(Thread.currentThread().getName()+"

在运行"

demo.setDaemon(true);

虽然有一个死循环,但是程序还是可以执行完的。

因为在死循环中的线程操作已经设置为后台运行了。

线程的优先级:

*@authorRollen-Holt线程的优先级

运行"

Threadh1=newThread(newhello(),"

Threadh2=newThread(newhello(),"

Threadh3=newThread(newhello(),"

C"

h1.setPriority(8);

h2.setPriority

(2);

h3.setPriority(6);

A运行0

A运行1

A运行2

A运行3

A运行4

B运行0

C运行0

C运行1

C运行2

C运行3

C运行4

B运行1

B运行2

B运行3

B运行4

但是请读者不要误以为优先级越高就先执行。

谁先执行还是取决于谁先去的CPU的资源、

另外,主线程的优先级是5.

线程的礼让。

在线程操作中,也可以使用yield()方法,将一个线程的操作暂时交给其他线程执行。

if(i==3){

线程的礼让"

Thread.currentTh

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 经管营销 > 生产经营管理

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2