Java 线程实例讲解综述.docx

上传人:b****3 文档编号:2876509 上传时间:2022-11-16 格式:DOCX 页数:13 大小:27.25KB
下载 相关 举报
Java 线程实例讲解综述.docx_第1页
第1页 / 共13页
Java 线程实例讲解综述.docx_第2页
第2页 / 共13页
Java 线程实例讲解综述.docx_第3页
第3页 / 共13页
Java 线程实例讲解综述.docx_第4页
第4页 / 共13页
Java 线程实例讲解综述.docx_第5页
第5页 / 共13页
点击查看更多>>
下载资源
资源描述

Java 线程实例讲解综述.docx

《Java 线程实例讲解综述.docx》由会员分享,可在线阅读,更多相关《Java 线程实例讲解综述.docx(13页珍藏版)》请在冰豆网上搜索。

Java 线程实例讲解综述.docx

Java线程实例讲解综述

Java线程实例讲解综述

java2007-03-2311:

38:

16阅读14评论0  字号:

大中小 订阅

编写具有多线程能力的程序经常会用到的方法有:

  run(),start(),wait(),notify(),notifyAll(),sleep(),yield(),join()

  还有一个重要的关键字:

synchronized

  本文将对以上内容进行讲解。

  一:

run()和start()

  示例1:

publicclassThreadTestextendsThread{

publicvoidrun(){

for(inti=0;i<10;i++){

System.out.print(""+i);

}

}

publicstaticvoidmain(String[]args){

newThreadTest().start();

newThreadTest().start();

}

}

  这是个简单的多线程程序。

run()和start()是大家都很熟悉的两个方法。

把希望并行处理的代码都放在run()中;stat()用于自动调用run(),

这是JAVA的内在机制规定的。

并且run()的访问控制符必须是public,返回值必须是void(这种说法不准确,run()没有返回值),run()

不带参数。

  这些规定想必大家都早已知道了,但你是否清楚为什么run方法必须声明成这样的形式?

这涉及到JAVA的方法覆盖和重载的规定。

这些内容很重要,

请读者参考相关资料。

  二:

关键字synchronized

  有了synchronized关键字,多线程程序的运行结果将变得可以控制。

synchronized关键字用于保护共享数据。

请大家注意"共享数据",

你一定要分清哪些数据是共享数据,JAVA是面向对象的程序设计语言,所以初学者在编写多线程程序时,容易分不清哪些数据是共享数据。

请看下面的例子:

  示例2:

publicclassThreadTestimplementsRunnable{

publicsynchronizedvoidrun(){

for(inti=0;i<10;i++){

System.out.print(""+i);

}

}

publicstaticvoidmain(String[]args){

Runnabler1=newThreadTest();

Runnabler2=newThreadTest();

Threadt1=newThread(r1);

Threadt2=newThread(r2);

t1.start();

t2.start();

}

}

  在这个程序中,run()被加上了synchronized关键字。

在main方法中创建了两个线程。

你可能会认为此程序的运行结果一定为:

0123456789

0123456789。

但你错了!

这个程序中synchronized关键字保护的不是共享数据(

其实在这个程序中synchronized关键字没有起到任何作用,此程序的运行结果是不可预先确定的)。

这个程序中的t1,t2是两个对象(r1,

r2)的线程。

JAVA是面向对象的程序设计语言,不同的对象的数据是不同的,r1,

r2有各自的run()方法,而synchronized使同一个对象的多个线程,

在某个时刻只有其中的一个线程可以访问这个对象的synchronized数据。

每个对象都有一个"锁标志",

当这个对象的一个线程访问这个对象的某个synchronized数据时,这个对象的所有被synchronized修饰的数据将被上锁(因为"锁标志"

被当前线程拿走了),只有当前线程访问完它要访问的synchronized数据时,当前线程才会释放"锁标志",

这样同一个对象的其它线程才有机会访问synchronized数据。

  示例3:

publicclassThreadTestimplementsRunnable{

publicsynchronizedvoidrun(){

for(inti=0;i<10;i++){

System.out.print(""+i);

}

}

publicstaticvoidmain(String[]args){

Runnabler=newThreadTest();

Threadt1=newThread(r);

Threadt2=newThread(r);

t1.start();

t2.start();

}

}

  如果你运行1000次这个程序,它的输出结果也一定每次都是:

01234567890123456789。

因为这里的synchronized保护的是共享数据。

t1,

t2是同一个对象(r)的两个线程,当其中的一个线程(例如:

t1)开始执行run()方法时,由于run()受synchronized保护,所以同一个对象的其他线程(

t2)无法访问synchronized方法(run方法)。

只有当t1执行完后t2才有机会执行。

  示例4:

publicclassThreadTestimplementsRunnable{

publicvoidrun(){

synchronized(this){

for(inti=0;i<10;i++){

System.out.print(""+i);

}

}

}

publicstaticvoidmain(String[]args){

Runnabler=newThreadTest();

Threadt1=newThread(r);

Threadt2=newThread(r);

t1.start();

t2.start();

}

}

  这个程序与示例3的运行结果一样。

在可能的情况下,应该把保护范围缩到最小,可以用示例4的形式,this代表"这个对象"。

没有必要把整个run()保护起来,

run()中的代码只有一个for循环,所以只要保护for循环就可以了。

  示例5:

publicclassThreadTestimplementsRunnable{

publicvoidrun(){

for(intk=0;k<5;k++){

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

+":

forloop:

"+k);

}

synchronized(this){

for(intk=0;k<5;k++){

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

+":

synchronizedforloop:

"+k);

}

}

}

publicstaticvoidmain(String[]args){

Runnabler=newThreadTest();

Threadt1=newThread(r,"t1_name");

Threadt2=newThread(r,"t2_name");

t1.start();

t2.start();

}

}

运行结果:

t1_name:

forloop:

0

t1_name:

forloop:

1

t1_name:

forloop:

2

t2_name:

forloop:

0

t1_name:

forloop:

3

t2_name:

forloop:

1

t1_name:

forloop:

4

t2_name:

forloop:

2

t1_name:

synchronizedforloop:

0

t2_name:

forloop:

3

t1_name:

synchronizedforloop:

1

t2_name:

forloop:

4

t1_name:

synchronizedforloop:

2

t1_name:

synchronizedforloop:

3

t1_name:

synchronizedforloop:

4

t2_name:

synchronizedforloop:

0

t2_name:

synchronizedforloop:

1

t2_name:

synchronizedforloop:

2

t2_name:

synchronizedforloop:

3

t2_name:

synchronizedforloop:

4

  第一个for循环没有受synchronized保护。

对于第一个for循环,t1,

t2可以同时访问。

运行结果表明t1执行到了k=2时,t2开始执行了。

t1首先执行完了第一个for循环,此时还没有执行完第一个for循环(

t2刚执行到k=2)。

t1开始执行第二个for循环,当t1的第二个for循环执行到k=1时,t2的第一个for循环执行完了。

t2想开始执行第二个for循环,但由于t1首先执行了第二个for循环,这个对象的锁标志自然在t1手中(

synchronized方法的执行权也就落到了t1手中),在t1没执行完第二个for循环的时候,它是不会释放锁标志的。

所以t2必须等到t1执行完第二个for循环后,它才可以执行第二个for循环

三:

sleep()

  示例6:

publicclassThreadTestimplementsRunnable{

publicvoidrun(){

for(intk=0;k<5;k++){

if(k==2){

try{

Thread.currentThread().sleep(5000);

}

catch(Exceptione){}

}

System.out.print(""+k);

}

}

publicstaticvoidmain(String[]args){

Runnabler=newThreadTest();

Threadt=newThread(r);

t.start();

}

}

  sleep方法会使当前的线程暂停执行一定时间(给其它线程运行机会)。

读者可以运行示例6,看看结果就明白了。

sleep方法会抛出异常,必须提供捕获代码。

  示例7:

publicclassThreadTestimplementsRunnable{

publicvoidrun(){

for(intk=0;

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

当前位置:首页 > 初中教育 > 政史地

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1