Java语言程序设计郑莉第八章课后习题答案.docx

上传人:b****6 文档编号:8599706 上传时间:2023-02-01 格式:DOCX 页数:20 大小:197.54KB
下载 相关 举报
Java语言程序设计郑莉第八章课后习题答案.docx_第1页
第1页 / 共20页
Java语言程序设计郑莉第八章课后习题答案.docx_第2页
第2页 / 共20页
Java语言程序设计郑莉第八章课后习题答案.docx_第3页
第3页 / 共20页
Java语言程序设计郑莉第八章课后习题答案.docx_第4页
第4页 / 共20页
Java语言程序设计郑莉第八章课后习题答案.docx_第5页
第5页 / 共20页
点击查看更多>>
下载资源
资源描述

Java语言程序设计郑莉第八章课后习题答案.docx

《Java语言程序设计郑莉第八章课后习题答案.docx》由会员分享,可在线阅读,更多相关《Java语言程序设计郑莉第八章课后习题答案.docx(20页珍藏版)》请在冰豆网上搜索。

Java语言程序设计郑莉第八章课后习题答案.docx

Java语言程序设计郑莉第八章课后习题答案

Java语言程序设计

第八章课后习题答案

1.进程和线程有何区别,Java是如何实现多线程的。

答:

区别:

一个程序至少有一个进程,一个进程至少有一个线程;线程的划分尺度小于进程;进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。

Java程序一般是继承Thread类或者实现Runnable接口,从而实现多线程。

2.简述线程的生命周期,重点注意线程阻塞的几种情况,以及如何重回就绪状态。

答:

线程的声明周期:

新建-就绪-(阻塞)-运行--死亡

线程阻塞的情况:

休眠、进入对象wait池等待、进入对象lock池等待;

休眠时间到回到就绪状态;在wait池中获得notify()进入lock池,然后获得锁棋标进入就绪状态。

3.随便选择两个城市作为预选旅游目标。

实现两个独立的线程分别显示10次城市名,每次显示后休眠一段随机时间(1000毫秒以内),哪个先显示完毕,就决定去哪个城市。

分别用Runnable接口和Thread类实现。

(注:

两个类,相同一个测试类)

//Runnable接口实现的线程runable类

publicclassrunnableimplementsRunnable{

privateStringcity;

publicrunnable(){}

publicrunnable(Stringcity){

this.city=city;

}

publicvoidrun(){

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

System.out.println(city);

try{

//休眠1000毫秒。

Thread.sleep(1000);

}catch(InterruptedExceptione){

e.printStackTrace();

}

}

}

}

//Thread类实现的线程thread类

publicclassrunnableextendsThread{

privateStringcity;

publicrunnable(){}

publicrunnable(Stringcity){

this.city=city;

}

publicvoidrun(){

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

System.out.println(city);

try{

//休眠1000毫秒。

Thread.sleep(1000);

}catch(InterruptedExceptione){

e.printStackTrace();

}

}

}

}

 

//test8_3

publicclasstest8_3{

publicstaticvoidmain(String[]args){

//将创建一个线程对象,这个对象接受一个实现了Runnable接口。

实际上这里也就是使用run()方法

runnabler1=newrunnable("广州");

runnabler2=newrunnable("乌鲁木齐");

Threadt1=newThread(r1);

Threadt2=newThread(r2);

//启动线程

t1.start();

t2.start();

}

}

 

运行结果分别为:

 

4.编写一个多线程程序实现如下功能:

线程A和线程B分别在屏幕上显示信息“…start”后,调用wait等待;线程C开始后调用sleep休眠一段时间,然后调用notifyall,使线程A和线程B继续运行。

线程A和线程B恢复运行后输出信息“…end”后结束,线程C在判断线程B和线程A结束后自己结束运行。

//test8_4

publicclasstest8_4{

ThreadA=newThread("A"){

publicvoidrun(){

Wait("A");

}

};

ThreadB=newThread("B"){

publicvoidrun(){

Wait("B");

}

};

ThreadC=newThread("C"){

publicvoidrun(){

while(true){

if(!

A.isAlive()&&!

B.isAlive())

return;

try{

Thread.sleep(2000);

}catch(InterruptedExceptione){

e.printStackTrace();

}

notifyall();

}

}

};

publicsynchronizedvoidWait(Stringname){

System.out.println(name+"..start");

try{

wait();

}catch(InterruptedExceptione){

e.printStackTrace();

}

System.out.println(name+"..end");

}

publicsynchronizedvoidnotifyall(){

notifyAll();

}

publicstaticvoidmain(Stringargs[]){

test8_4test=newtest8_4();

//A、B两线程一起输入start和输出end,不过中间有C让线程休眠2秒,没法全部一次性输出,

//之后再唤醒,让AB继续输出下半部分end

test.A.start();

test.B.start();

test.C.start();

}

}

运行结果:

 

5.实现一个数据单元,包括学号和姓名两部分。

编写两个线程,一个线程往数据单元中写,另一个线程往外读。

要求没写一次就往外读一次。

//Data类

importjava.util.Scanner;

publicclassData{

StringstudentId;

Stringname;

booleanavailable=false;//判断是读是写

Scannerin=newScanner(System.in);//定义一个输入对象

publicsynchronizedvoidread()

{

if(available)

try

{

wait();

}

catch(Exceptione)

{

}

System.out.printf("请输入学号:

");

try

{

studentId=in.next();

}

catch(Exceptione)

{

System.out.println("输入学号出错!

");

}

System.out.printf("请输入姓名:

");

try

{

name=in.next();

}

catch(Exceptione)

{

System.out.println("输入姓名出错!

");

}

System.out.println();

available=true;

notify();

}

publicsynchronizedvoidwrite()

{

if(!

available)

try

{

wait();

}

catch(Exceptione)

{

}

System.out.println("输出学生学号:

"+studentId+"姓名:

"+name+"\n");

available=false;

notify();

}

}

//Read类

publicclassReadextendsThread{

Datad1=null;

publicRead(Datad){

this.d1=d;

}

publicvoidrun(){

while(true)

{

d1.read();

}

}

}

//Write类

classWriteextendsThread{

Datad2=null;

publicWrite(Datad)

{

this.d2=d;

}

publicvoidrun()

{

while(true)

{

d2.write();

}

}

}

//test8_5类

publicclasstest8_5{

publicstaticvoidmain(String[]args){

Datadata=newData();

newRead(data).start();

newWrite(data).start();

}

}

运行结果:

6.创建两个不同优先级的线程,都从1数到10000,看看哪个数得快。

(注:

线程的优先级别越高低与执行速度没有绝对关系!

//Count类

publicclassCountextendsThread{

intwhich;

intn=10000;

publicCount(intwhich){

this.which=which;

}

publicvoidrun(){

for(inti=1;i<=n;i++){

if(i==n){

System.out.println(which+"号进程"+"结束!

");

}

}

}

}

//test8_6

publicclasstest8_6{

publicstaticvoidmain(String[]args){

Countcount1=newCount

(1);

Countcount2=newCount

(2);

Threadt1=newThread(count1);

Threadt2=newThread(count2);

t1.setPriority

(2);//1号进程优先级是2

t2.setPriority(8);//2号进程优先级是8

t1.start();

t2.start();

}

}

运行结果:

都有可能。

 

7.编写一个Java程序,以说明较高优先级的线程通过调用sleep方法,使较低优先级的线程获得运行的机会。

(这里可以借鉴课本例8—13)

//TestThread类

publicclassTestThreadextendsThread{

privateinttick=1;

privateintnum;

publicTestThread(inti){

this.num=i;

}

publicvoidrun(){

while(tick<400000){

tick++;

if((tick%50000)==0){

System.out.println("Thread#"+num+",tick="+tick);

yield();

try{

sleep

(1);

}catch(Exceptione){

}

}

}

}

}

//test8_7

publicclasstest8_7{

publicstaticvoidmain(String[]args){

TestThread[]runners=newTestThread[2];

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

runners[i]=newTestThread(i);

}

runners[0].setPriority

(2);

runners[1].setPriority(5);

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

runners[i].start();

}

}

}

运行结果:

8.主线程控制新线程的生命,当主线程运行一段时间后,控制新线程死亡,主线程继续运行一段时间后结束。

(注:

main函数就是主线程,程序里其他的Thread都属于子线程。

可以参考课本的例8—1)

//SonThread类

publicclassSonThreadextendsThread{

privateintnum;

publicSonThread(intnum){

this.num=num;

}

publicvoidrun(){

inti=num;

intresult=1;

System.out.println("newthreadstart.");

/*while(i>0){

result=result*i;

i--;

}*/

System.out.println("thenewthreadof"+num+"is"+result);

System.out.println("newthreadends");

}

}

//test8_8

publicclasstest8_8{

publicstaticvoidmain(String[]args){

System.out.println("maintreadstart.");

SonThreadnewThread=newSonThread(10);

newThread.start();

//;浪费时间的循环

inti=1;

while(i<=100000){

i++;

}

newThread.stop();//结束新进程

System.out.println("mainthreadends");

}

}

 

运行结果:

(这个结果很难把握,通常都会出现2那样的结果,知道原理就好。

2

 

9.用两个线程模拟存、取货物。

一个线程往一对象里放货物(包括品名、价格),另外一个线程取货物。

分别模拟“放一个、取一个”和“放若干个、取若干个”两种情况。

//Good货物类

publicclassGood{

Stringname;

intprice;

publicGood(){

}

publicGood(Stringname,intprice){

this.name=name;

this.price=price;

}

publicGood(Goodg){

this.name=g.name;

this.price=g.price;

}

}

//WareHouse仓库类

importjava.util.ArrayList;

importjava.util.List;

importjava.util.Scanner;

publicclassWareHouse{

Goodgood=null;

Scannerin=newScanner(System.in);

Listlist=newArrayList();//用来存放商品对象

intcount;//想存入商品的个数

booleanavailable=true;

publicWareHouse(){

}

publicWareHouse(intcount){

this.count=count;

}

publicWareHouse(Listlist){

this.count=count;

for(inti=0;i

this.list.add((Good)list.get(i));

}

}

publicsynchronizedvoidsaveGood(){

if(available==false){

try{

wait();

}catch(InterruptedExceptione){

//TODOAuto-generatedcatchblock

e.printStackTrace();

}

}

for(inti=0;i

Stringn;

intp;

System.out.println("请输入"+(i+1)+"号商品的名称:

");

n=in.next();

System.out.println("价格:

");

p=in.nextInt();

good=newGood(n,p);

list.add(good);

}

available=false;

notify();

}

publicsynchronizedvoidtakeGood(){

if(available==true){

try{

wait();

}catch(InterruptedExceptione){

//TODOAuto-generatedcatchblock

e.printStackTrace();

}

}

for(inti=0;i

good=(Good)list.get(i);

System.out.print((i+1)+"号商品的名称为:

"+good.name);

System.out.println("\t价格为:

"+good.price);

}

available=true;

notify();

}

}

//Save存货物类

publicclassSaveextendsThread{

WareHousewareHouse=null;

publicSave(WareHousew){

this.wareHouse=w;

}

publicvoidrun(){

wareHouse.saveGood();

}

}

//Take取货物类

publicclassTakeextendsThread{

WareHousewareHouse=null;

publicTake(WareHousew){

this.wareHouse=w;

}

publicvoidrun(){

wareHouse.takeGood();

}

}

//test8_9测试类

importjava.util.Scanner;

publicclasstest8_9{

publicstaticvoidmain(String[]args){

Scannerin=newScanner(System.in);

System.out.println("请输入仓库的容量:

");

inti=in.nextInt();

WareHousewareHouse=newWareHouse(i);

ThreadsaveGood=newSave(wareHouse);

ThreadtakeGood=newTake(wareHouse);

saveGood.start();

takeGood.start();

}

}

运行结果:

 

10.用两个线程模拟对话,任何一个线程都可以随时收发信息。

(这道题本人搞不清楚,暂且用网上的给大家参考下。

听说要用到:

Socket.getInputStream()获取输入流用于“接收”

Socket.getOutputStream()获取输出流用于“发送”

//test8_10

importjava.io.*;

import.*;

importjava.util.*;

publicclasstest8_10{

publicstaticvoidmain(String[]args){

try{

//establishserversocket

ServerSockets=newServerSocket(8189);

//waitforclientconnection

Socketincoming=s.accept();

try{

InputStreaminStream=incoming.getInputStream();

OutputStreamoutStream=incoming.getOutputStream();

Scannerin=newScanner(inStream);

PrintWriterout=newPrintWriter(outStream,true);

out.println("Hello!

EnterBYEtoexit.");

//echoclientinput

booleandone=false;

while(!

done&&in.hasNextLine()){

Stringline=in.nextLine();

out.println("Echo:

"+line);

if(line.trim().equals("BYE"))

done=true;

}

}finally{

incoming.close();

}

}catch(IOExceptione){

e.printStackTrace();

}

}

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

当前位置:首页 > 经管营销 > 企业管理

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

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