admin 管理员组文章数量: 1086019
2024年12月30日发(作者:java程序设计教程雍俊海课后答案)
《Java语言程序设计基础教程》
练习思考题参考答案
第1章 Java程序设计概述
1.1单项选择题
1.编译Java Application源文件将产生相应的字节码文件,扩展名是什么
A. .java
C. .html
解答:B
B. .class
D. .exe
2.Java语言具有许多优点和特点,下列选项中,哪个反映了Java中“一次编译,
随处运行”的特点。
A. 简单性
C. 面向对象性
解答:B
3.Java语言具有许多优点和特点,下列选项中,哪个反映了Java中并行机制的
特点。
A. 多线程
C. 面向对象性
解答:A
B. 平台无关性
D. 安全性
B. 平台无关性
D. 安全性
4.在Java语言中,下列哪些语句关于内存回收的说明是正确的?
A.程序员必须创建一个线程来释放内存;
B.内存回收程序负责释放无用内存 ;
C.内存回收程序允许程序员直接释放内存 ;
D.内存回收程序可以在指定的时间释放内存对象
解答:B
5.一个Java源文件中最多只能有多少个public类。
A. 1个 B. 2个
C. 3个 D. 任意多个
1
解答:A
6.下面哪一个不是Java语言所具有的特点。
A. 没有全局变量,在类的定义外部没有任何的变量定义;
B. 不直接支持指针操作,而使用更安全的引用类型;
C. 支持子类对父类的多继承;
D. 具有自动垃圾收集功能;
解答:C
7.下面哪一个不是Java开发工具包JDK的组成部分。
A. Java的编译器;
B. Java的解释器;
C. Java的API继承类库;
D. Eclipse开发工具;
解答:C
8.JDK提供的编译器是( )。
A. B.
C. D.
解答:B
9.作为Java应用程序入口的main方法,其声明格式可以是( )
A. public void main(String [] args)
B. public static void main(String [] args)
C. public static void Main(String * args)
D. public int main(String [] args)
解答:B
10.下列说法正确的是( A )
A、 JAVA程序的main方法必须写在类里面
B、 JAVA程序中可以有多个main方法
C、 JAVA程序中类名必须与文件名一样
D、 JAVA程序的main方法中如果只有一条语句,可以不用{}(大括号)括起来
11.下列哪些语句关于Java内存回收的说明是正确的? ( B )
A、程序员必须创建一个线程来释放内存
B、内存回收程序负责释放无用内存
2
C、内存回收程序允许程序员直接释放内存
D、内存回收程序可以在指定的时间释放内存对象
1.2填空题
1、 开发与运行Java程序需要经过的三个主要步骤为____________、____________和
____________。
解答:
编辑源程序 、编译生成字节码和解释运行字节码
2、使用Java编译器___ javac____.exe编译源文件得到字节码文件。
3、Java应用程序必须通过Java解释器__JAVA__.exe来解释执行其字节码文件。
4、如果Java源文件中有一个类是public类,那么源文件的名字必须与这个类的名字完
全_相同______,扩展名是.java 。
5、Java应用程序总是从主类的____main___方法开始执行.
1.3简答题
13.简述Java程序的开发过程?
(1)使用一个文字编辑器,编写源文件。(2)使用java编译器,编译源文件得到字节
码文件。
(3)解释运行字节码,分两种java应用程序必须通过java解释器来解释执行,java小
应用程序必须使用解释器和浏览器运行程序。
1.什么是Java虚拟机?为什么Java被称作是“平台无关的编程语言”?
解答:
Java虚拟机是一个可以执行Java字节码的虚拟机进程。Java源文件被编译成能被Java
虚拟机执行的字节码文件。
Java被设计成允许应用程序可以运行在任意的平台,而不需要程序员为每一个平台单独
重写或者是重新编译。Java虚拟机让这个变为可能,因为它知道底层硬件平台的指令长度和
其他特性。
语言的关键特点有哪些?
解答:
简单性
平台无关性
面向对象性
安全性
3
分布式
多线程
动态性
1.4综合题
第2章 Java基本的程序设计结构
2.1单项选择题
1、 下面哪一项在java中是非法的标识符?( )
A. $user
B. point
C. You&me
D. _endline
解答:C
2、 若有定义 int a=9,b=6; 那么a>b的值是:( )
A. 0 B. 1
C. false D. true
解答:D
3、执行完以下代码int[ ] x = new int[25];后,以下说明正确的是:(
A. x[24]为0 B. x[24]未定义
C. x[25]为0 D. x[0]为空
解答:A
4、Java应用程序的main方法中有以下语句,则输出的结果是(
int[] x={2,3,-8,7,9};
int max=x[0];
for(int i=1;i<;i++){
if(x[i]>max)
max=x[i];
}
n(max);
A. 2 B. -8
C. 7 D. 9
解答:D
5、设 x = 1 , y = 2 , z = 3,则表达式 y+=z--/++x 的值是(
A. 3 B. 3.5
C. 4 D. 5
解答:A
4
)
。
)
)
5、执行n(5/4),这条代码的输出结果是( )
A. 1 B. 1.25
C. 1.5 D. 0
解答:A
6、下列语句有错误的是:( )
A. int []a; B. int []b=new int[10];
C. int c[]=new int[]; D. int d[]=null;
解答:C
7、下列语句有错误的是:( )
A. int a[][]=new int[5][5]; B. int [][]b=new int[5][5];
C. int []c[]=new int[5][5]; D. int [][]d=new int[5,5];
解答:D
8、下列哪一个不属于Java中的8种基本数据类型( )
A. double; ;
C. int; D. String;
解答:D
9、以下数据类型存储空间最大的是( )。
(A)byte (B)long (C)float (D)char
解答:B
10、n("5" + 2);的输出结果应该是()。
A 52 B7
C2 D5
答案:A
11.在类的定义中可以有两个同名方法,每个方法的参数不同,这种现象称为方法(D )。
(A)封装 (B)继承 (C)覆盖 (D)重载
12.java中定义字符串String s=”pzhu”,下面操作可以取得字符串长度的是( )。
A. () B. C. () D. length(s)
解答:A
13.指出下列程序运行的结果 (B)(很难)
public class Example {
String str = new String("good");
char[] ch = { 'a', 'b', 'c' };
public static void main(String args[]) {
Example ex = new Example();
(, );
( + " and ");
();
5
}
public void change(String str, char ch[]) {
str = "test ok";
ch[0] = 'g';
}
}
A、 good and abc
B、 good and gbc
C、 test ok and abc
D、 test ok and gbc
14.下面代码的运行结果为:(C)(较难)
import .*;
import .*;
public class foo{
public static void main (String[] args){
String s;
n("s=" + s);
}
}
A 代码得到编译,并输出“s=”
B 代码得到编译,并输出“s=null”
C 由于String s没有初始化,代码不能编译通过
D 代码得到编译,但捕获到 NullPointException异常
15.关于以下程序段,正确的说法是( C )
1. String s1=”abc”+”def”;
2. String s2=new String(s1);
3. if(s1= =s2)
4. n(“= = succeeded”);
5. if ((s2))
6. n(“.equals() succeeded”);
A、行4与行6都将执行
B、行4执行,行6不执行
6
C、行6执行,行4不执行
D、行4、行6都不执行
16.Java application中的主类需包含main方法,main方法的返回类型是什么?( D )
A、int B、float
C、double D、void
17.为一个boolean类型变量赋值时,可以使用(B )方式
A、 boolean = 1;
B、 boolean a = (9 >= 10);
C、 boolean a="真";
D、 boolean a = = false;
18.表达式(11+3*8)/4%3的值是( D )
A、 31 B、 0 C、 1 D、 2
19.运算符优先级别排序正确的是( A) (太难)
A、 由高向低分别是:()、!、算术运算符、关系运算符、逻辑运算符、赋值运算符;
B、 由高向低分别是:()、关系运算符、算术运算符、赋值运算符、!、逻辑运算符;
C、 由高向低分别是:()、算术运算符、逻辑运算符、关系运算符、!、赋值运算符;
D、 由高向低分别是:()、!、关系运算符、赋值运算符、算术运算符、逻辑运算符;
20.下列值不为true的表达式有(C )。
A、 "john" = = "john"
B、 "john".equals("john")
C、 "john" = "john"
D、 "john".equals(new String("john"))
21、下面的方法,当输入为2的时候返回值是多少?(D)(很难)
public static int getValue(int i) {
int result = 0;
switch (i) {
case 1:
result = result + i;
case 2:
result = result + i * 2;
case 3:
result = result + i * 3;
}
return result;
}
A0 B2 C4 D10
答案:D
7
解析:注意这里case后面没有加break,所以从case 2开始一直往下运行。
22、下面有关for循环的描述正确的是( A )
A、 for循环体语句中,可以包含多条语句,但要用大括号括起来
B、 for循环只能用于循环次数已经确定的情况
C、 在for循环中,不能使用break语句跳出循环
D、 for循环是先执行循环体语句,后进行条件判断
23、score是一个整数数组,有五个元素,已经正确初始化并赋值,仔细阅读下面代码,
程序运行结果是( B )
temp = score[0];
for (int index = 1;index < 5;index++) {
if (score[index] < temp) {
temp = score[index];
}
}
A. 求最大数 B. 求最小数 C. 找到数组最后一个元素 D. 编译出错
26、
2.2填空题
1、Java语言是一种完全的_面向对象 _程序设计语言
2、String s1=“China”; int n=( ); n的值为_5__
3、在Java语言中,基本数据类型包括:____整数类型、____浮点类型、____字符类型
_和____布尔类型
17、在Java的基本数据类型中,char型采用Unicode编码方案,每个Unicode码占用
__2___字节内存空间,这样,无论是中文字符还是英文字符,都是占用__2___字节内存空间。
18、设 x = 2 ,则表达式 ( x + + )/3 的值是__0___。
20、设有数组定义:
int MyIntArray[] = { 10, 20, 30, 40, 50, 60, 70 };
则执行以下几个语句后的输出结果是: 120 。
8
int MyIntArray[] = { 10, 20, 30, 40, 50, 60, 70 };
int s = 0;
for (int i = 0; i < ; i++)
if (i % 2 == 1)
s += MyIntArray[i];
n(s);
21、数组对象的长度在数组对象创建之后,就__不会____改变。数组元素的下标总是从
___0___开始。
22、对于数组int[][]t={{1,2,3},{4,5,6}}来说,等于__2___,t[0].length等于__3____。
2.3简答题
1、Java的基本数据类型有哪8种,每种类型的内存空间分别是多少。
2.4综合题
26、编程计算10~20的整数的平方值,将结果保存在一个数组中。
27、编写一个程序使之从键盘读入10个整数存入整型数组a中,并输出这10个整数的
最大值和最小值。
import r;
public class lianxi30 {
public static void main(String args[]) {
Scanner temp;
float[] sum = new float[11];
float max, min;
for (int i = 0; i < 10; i++) {
System.
out
.println("请输入第一个数字(回车结束):");
temp = new Scanner(System.
in
);
String a = ne();
sum[i] = Integer.
parseInt
(a); //获取输入的字符串
}
max = sum[0];
min = sum[0];
for (int j = 1; j < 10; j++)
{
if (max < sum[j])
max = sum[j];
else if (min > sum[j])
min = sum[j];
}
9
System.
out
.println(max);
System.
out
.println(min);
}
}
31、如果我国经济以每年10%的速度保持稳定增长,请编写一个程序,计算每年达到
多少,多少年可以实现总量翻两番。
class exA4_1{
public static void main(String args[]){
int a=0;
double i=0.10,sum=1;
while(sum<=4){
sum=(i+1)*sum;
a++;
n("第"+a+"年达到"+sum);
}
n("需要"+a+"年实现两番");
}
}
第3章 类和对象
3.1单项选择题
1、 下列关于变量的叙述哪个是错的?( )
A. 实例变量是类的成员变量。
B. 在方法中定义的局部变量在该方法被执行时创建。
C. 实例变量用关键字static声明。
D. 局部变量在使用前必须被初始化。
解答:C
2、 在Java语言中,下列哪个包是编译器自动导入的?(
A. B.
C. D.
解答:B
6、 不允许作为类及类成员的访问控制符的是( )。
A. public B. private
10
)
C. static D. protected
解答:C
7、 为AB类的一个无形式参数无返回值的方法method书写方法头,使得使用类名AB
作为前缀就可以调用它,该方法头的形式为( )。
A、 static void method( ) B、 public void method( )
C、 final void method( ) D、 abstract void method( )
解答:A
8、 可以在下面代码段point x处写入的是?( )
//point x
public class Interesting{
//do something
}
A. String str;
B. static int PI=3.14;
C. public class MyClass{//do other thing…}
D. import .*;
解答:D
9、Java提供的许多类在不同的包中,使用下面哪个语句可以引入包中的类。
A. package B. include
C. import D. add
解答:C
11、已知A类被打包在packageA , B类被打包在packageB ,且B类被声明为public ,
且有一个成员变量x被声明为protected控制方式 。C类也位于packageA包,且继承了B
类 。则以下说法正确的是:( )
A、A类的实例不能访问到B类的实例
B、A类的实例能够访问到B类一个实例的x成员
C、C类的实例可以访问到B类一个实例的x成员
D、C类的实例不能访问到B类的实例
解答:C(太难)
13、在Java中,关于final关键字的说法正确的是( )
A、如果修饰变量,则一旦赋了值,就等同一个常量。
B、如果修饰类,则该类只能被一个子类继承。
C、如果修饰方法,则该方法不能在子类中被覆盖。
D、如果修饰方法,则该方法所在的类不能被继承。
解答:A,C
14、关于构造方法以下说法错误的是 ( D )。
(A)构造方法名必须与类名一致 (B)构造方法可以重载
(C)构造方法是通过new来调用 (D)每个类都必须编写构造方法代码
15、关于类的定义以下说法错误( B )。
(A)类定义使用class关键字 (B)每个类中必须有一个main方法
(C)一个包可以包含多个类 (D)java中所有类都是Object类的子类
16、在创建对象时必须(C)
A) 先声明对象,然后才能使用对象
11
B) 先声明对象,为对象分配内存空间,然后才能使用对象
C) 先声明对象,为对象分配内存空间,对对象初始化,然后才能使用对象
D) 上述说法都对
17、在调用方法时,若要使方法改变实参的值,可以(B)
A) 用基本数据类型作为参数 B) 用对象作为参数
C) A和B都对 D) A和B都不对
18、关于以下程序代码的说明正确的是( D )
class HasStatic{
private static int x=100;
public static void main(String args[ ]){
HasStatic hs1=new HasStatic( );
hs1.x++;
HasStatic hs2=new HasStatic( );
hs2.x++;
hs1=new HasStatic( );
hs1.x++;
HasStatic.x- -;
n(“x=”+x);
}
}
A、 5行不能通过编译,因为引用了私有静态变量
B、 10行不能通过编译,因为x是私有静态变量
C、 程序通过编译,输出结果为:x=103
D、 程序通过编译,输出结果为:x=102
19、以下关于构造函数的描述错误的是( A )。
A、构造函数的返回类型只能是void型。
B、构造函数是类的一种特殊函数,它的方法名必须与类名相同。
C、构造函数的主要作用是完成对类的对象的初始化工作。
D、一般在创建新对象时,系统会自动调用构造函数。
20、Java中,在如下所示的Test类中,共有(C )个构造方法。
public class Test{
private int x;
public Test(){ x=35; }
public void Test(double f){ This.x=(int)f; }
public Test(String s){}
}
A、 0 B、 1 C、 2 D、 3
21、在Java中,关于构造方法,下列说法错误的是( C )
A、 构造方法的名称必须与类名相同
B、 构造方法可以带参数
C、 构造方法不可以重载
12
D、 构造方法绝对不能有返回值
22、在Java语言中,下列关于类的继承的描述,正确的是(B )。
A、 一个类可以继承多个父类
B、 一个类可以具有多个子类
C、 子类可以使用父类的所有方法
D、 子类一定比父类有更多的成员方法
23、分析选项中关于Java中this关键字的说法正确的是( A )
A、 this关键字是在对象内部指代自身的引用
B、 this关键字可以在类中的任何位置使用
C、 this关键字和类关联,而不是和特定的对象关联
D、 同一个类的不同对象共用一个this
24、在Java接口中,下列选项中有效的方法声明是( A )。
A、 public void aMethod();
B、 public final void aMethod();
C、 protected void aMethod();
D、 private void aMethod();
25、下列选项中关于Java中super关键字的说法正确的是(A )。
A、 super关键字是在子类对象内部指代其父类对象的引用
B、 super关键字不仅可以指代子类的直接父类,还可以指代父类的父类
C、 子类通过super关键字只能调用父类的方法,而不能调用父类的属性
D、 子类通过super关键字只能调用父类的属性,而不能调用父类的方法
3.2填空题
1、在Java程序中,通过类的定义只能实现____单重继承____,但通过接口的定义可以
实现多____多重继承____。
2、_抽象(abstract)___方法是一种仅有方法头,没有具体方法体和操作实现的方法,
该方法必须在抽象类之中定义。__final____方法是不能被当前类的子类重新定义的方法。
3、面向对象程序设计的三个特征是_____封装、____多态、____继承
4、Java是面向对象语言,类是客观事物的_抽象____,而对象是类的_实例____。
5、如果在子类中想使用被子类隐藏的父类成员变量或方法,就可以使用关键字__
super_____。
6、Java中有一种叫作___构造方法__的特殊方法用来对类的对象成员进行初始化。
13
7、JAVA语言中提供了两种类型的字符串类来处理字符串,它们是___String_和
___StringBuffer类
8、Java语言中,所有 的类都是___Object的子类,Java的窗口通常是___JFrame__的子
类,___抽象_类只能定义但不能被实例化,_ 最终_类不能被继承
9、一般Java程序的类体由两部分组成:一部分是_属性_,另一部分是_方法_
10、分别用__class_关键字来定义类,用_new__关键字来分配实例存储空间。
11、Java中类成员的限定词有以下几种:__ private_ _, public __ _, protected __ _, _缺
省_ _。其中,_public __的限定的范围最大。类中限定为_ private __的成员,只能被这个类
本身内部访问。
12、Java类中,如果类的定义者没有显式的定义任何构造方法,系统将自动提供一个___
无参默认_构造方法。
13、在子类中定义与父类的相同的方法,若在多个子类中定义相同的方法,则可以调用不
同子类中的相同方法而实现不同的功能,这实现了程序运行时的______ 多态 。
3.3简答题
1. 简单阐述方法的重载和方法的重写之间的区别
解答:
重写是子类的方法覆盖父类的方法,要求方法名和参数都相同
重载是在同一个类中的两个或两个以上的方法,拥有相同的方法名,但是参数却不相同
2、 简述实例变量和类变量的区别。
解答:类变量也叫静态变量,也就是在变量前加了static 的变量;实例变量也叫对象变
量,即没加static 的变量;
区别在于:类变量是所有对象共有,其中一个对象将它值改变,其他对象得到的就是改
变后的结果;而实例变量则属对象私有,某一个对象将其值改变,不影响其他对象;
2、简述实例方法和类方法的区别
解答:实例方法可以对当前对象的实例变量进行操作,也可以对类变量进行操作,实例
方法由实例对象调用。但类方法不能访问实例变量,只能访问类变量。类方法可以由类名直
接调用,也可由实例对象进行调用。类方法中不能使用this或super关键字。
3、面向对象的三个基本特征是什么,分别简单介绍每个特征。
解答:三大特性是:封装,继承,多态。
封装性就是把对象的属性和服务结合成一个独立的单位,并尽可能隐蔽对象的内部细
节。
14
特殊类的对象拥有其一般类的全部属性与服务,称作特殊类对一般类的继承。
对象的多态性是指在一般类中定义的属性或服务被特殊类继承之后,可以具有不同的数
据类型或表现出不同的行为。这使得同一个属性或服务在一般类及其各个特殊类中具有不同
的语义。
4、简单阐述成员变量和局部变量的区别。
解答:
1)成员变量在整个类内都有效,局部变量只在定义它的方法内有效。
2)成员变量又分为实例成员变量(简称实例变量)和类变量(也称静态变量),如果成
员变量的类型前面加上关键字static,这样的成员变量称为类变量或静态变量。
3)如果局部变量的名字与成员变量的名字相同,则成员变量被隐藏,也就是说,这个成
员变量在这个方法内暂时失效。这时如果想在该方法内使用成员变量,必须使用关键字this。
5、 简述对象的引用和实体。
解答:当用类创建一个对象时,类中的成员变量被分配内存空间,这些内存空间称为该
对象的实体,而对象中存放着引用,以确保实体由该对象操作使用。没有实体的对象称为空
对象,空对象不能使用,即不能让一个空对象去调用方法产生行为。
6、简述this关键字的意义,以及它在成员方法和构造方法中如何使用。
解答:this是Java的一个关键字,表示某个对象。this可以出现在实例方法和构造方法
中,但不可以出现在类方法中。this可以出现在实例方法和构造方法中,但不可以出现在类
方法中。this关键字出现在类的构造方法中时,代表使用该构造方法所创建的对象。实例方
法必须通过对象来调用,当this关键字出现在类的实例方法中时,代表正在调用该方法的当
前对象。
成员函数中定义了和成员变量中相同的变量时,引用成员变量要用this;构造函数中调用
同一个类的其他构造函数时用this。
7、简单描述Java的参数传值中的两种方式,基本数据类型参数的传值和引用类型参数
的传值?
解答:在基本数据类型参数的传值中,基本数据类型的参数向该参数传递的值的级别不
可以高于该参数的级别。
在引用类型参数的传值中,Java的引用类型数据包括对象、数组和接口,当参数是引用
类型时,“传值”传递的是变量的引用而不是变量所引用的实体。如果改变参数变量所引用
的实体,就会导致原变量的实体发生同样的变化,但是如果改变参数的引用不会影响向其传
值的变量的引用。
8、基本数据类型和对象作为参数传递的不同?
解答:
(1) 基本数据类型作为参数在方法中传递的是值传递。
(2) 对象是引用传递,当对象作为参数传递时,传递的是对象的地址。
15
3.4综合题
1、定义一个“点”(Point)类用来表示三维空间中的点,类体的成员变量x,y,z分别表示
三维空间的坐标。类体中具有如下成员方法的定义:
1)构造方法Point()可以生成具有特定坐标的点对象。
2)setX(), setY(), setZ()为可以设置三个坐标的方法。
3.)getDistance()为可以计算该点距离原点距离平方的方法。
解答:
class Point{
double x,y,z ;
Point(double _x,double _y,double _z)
{
x = _x ;
y = _y ;
z =_z ;
}
void setX(double _x){
x=_x ;
}
void setY(double _y){
y=_y ;
}
void setZ(double _z){
z=_z ;
}
double getDistance(){
return ( x*x+y*y+z*z) ;
}
}
2、编写一个Java应用程序Test类,实现成员方法max(a,b)的重载。具体要求如下:
a) 编写void max(int a,int b)成员方法,对两个整数进行大小的比较,输出打印较大的那个
整数。
b) 编写void max(float a,float b)成员方法,对两个float数进行大小的比较,输出打印较大
的那个float数。
c) 编写void max(double a,double b)成员方法,对两个double数进行大小的比较,输出打印
较大的那个double数。
public class Test{
void max(int a,int b){
n(a>b ? a:b) ;
}
16
void max(float a,float b){
n(a>b ? a:b) ;
}
void max(double a, double b){
n(a>b ? a:b) ;
}
public static void main(String[] args){
Test t =new Test() ;
(3,4) ;
}
}
3、编写一个矩形类对数学中的矩形进行抽象描述,并具有方法可以计算矩形的周长和面积,
具体分为以下三个子任务完成。
(1)创建Rectangle类,添加属性width、height,并定义构造方法Rectangle(double _width,
double _height);
(2)在Rectangle类中添加两种方法computCircum()和computArea()分别计算矩形的周长和
面积;
(3)编程利用Rectangle对象输出一个30*40的矩形的周长和面积。
解答:
public class TestRectang {
}
class Rectangle{
Rectangle(){
}
Rectangle(double _width,double _height){
}
width = _width ;
height = _height ;
width = 0 ;
height = 0 ;
double width,height ;
public static void main(String[] args) {
}
// TODO Auto-generated method stub
Rectangle rect1 = new Rectangle(20,30) ;
n(Area());
n(Circum());
17
}
double computArea() {
}
double computCircum(){
}
return 2*(width+height) ;
return width*height ;
Java语言程序设计试题及答案
第八章 多线程
8.1建立线程有哪两种方法?
答:一是继承Thread类声明Thread子类,用Thread子类创建线程对象。二是在类中实
现Runnable接口,在类中提供Runnable接口的run()方法。无论用哪种方法,都需要java
基础类库中的Thread类及其方法的支持。程序员能控制的关键性工作有两个方面:一是编
写线程的run()方法;二是建立线程实例。
8.2怎样设置线程的优先级?
答:setPriority(int p),设定线程的优先级为p(1~10)。线程创建时,子线程继承父线程的
优先级。
优先级的数值越大优先级越高(缺省为5)。常用以下3个优先级:
_PRIORITY(最低)
_PRIORITY(最高)
_PRIORITY(标准)
8.3编写程序,一个画圆,一个画椭圆。
程序运行结果:
18
Applet的源文件:Work8_
import ;
import ;
import cs;
/**
* 8.3 用一个红色笔画圆,同时用一个蓝色笔画椭圆
*/
public class Work8_3 extends Applet implements Runnable
{
private static final long serialVersionUID = 1L;
/** 两个线程,红笔线程,和蓝笔线程 */
private Thread red_thread, blue_thread;
/** 红色画笔、蓝色画笔 */
private Graphics redPen, bluePen;
/** 蓝、红笔画时需要旋转角度 */
private int blue_angle = 0, red_angle = 0;
/** 红色画的图案的中心坐标 */
private int a_red = 100, b_red = 100;
/** 蓝色画的图案的中心坐标 */
private int a_blue = 300, b_blue = 100;
/**圆形半径*/
private int radius_red = 80;
/**椭圆的两个半径*/
private int radius1_blue = 150, radius2_blue = 100;
public void init()
{
red_thread = new Thread(this);
blue_thread = new Thread(this);
redPen = getGraphics();
bluePen = getGraphics();
setBackground();
setSize(470, 240);
}
public void start()
{
red_();// 两个线程开始
19
blue_();
}
public void run()
{
while (true)
{
if (tThread() == red_thread)
{
al(25, 25, 160, 160);// 绘制圆的边框。
x,y,width,height
int x = getX(radius_red, red_angle, a_red);
int y = getY(radius_red, red_angle, b_red);
or();
al(x, y, 10, 10);// 用白色画一次,可以擦出痕迹
red_angle += 3;
if (red_angle >= 360)
red_angle = 0;
x = getX(80, red_angle, 100);
y = getY(80, red_angle, 100);
or();
al(x, y, 10, 10);// 使用当前颜色填充外接指定矩
形框的椭圆
try
{
(10);
}
catch( InterruptedException e )
{
}
}
else if (tThread() == blue_thread)
{
al(a_blue / 2 + 5, b_blue / 2 - 45,
radius1_blue * 2,
radius2_blue * 2);// 绘制椭圆的边框。x,y,width,height
int x = getX(radius1_blue, blue_angle, a_blue);
int y = getY(radius2_blue, blue_angle, b_blue);
or();
al(x, y, 10, 10);// 擦除痕迹
blue_angle += 3;
if (blue_angle >= 360)
blue_angle = 0;
x = getX(radius1_blue, blue_angle, 300);
y = getY(radius2_blue, blue_angle, 100);
or();
al(x, y, 10, 10);// 擦除痕迹
try
{
(20);
}
catch( InterruptedException e )
{
}
}
}
20
}
}
/**
* 用参数方程方法,计算坐标的方法
* @param r 圆的半径,椭圆的两个半轴
* @param loc x坐标的相对偏移量
* @param angle 旋转的角度,单位为角度
* @return 计算后的坐标值
*/
public int getX(int r, int angle, int locX)
{
int x = locX + (int) (r * ( / 180.0 * angle));
return x;
}
/**
* 用参数方程方法,计算坐标的方法
* @param r 圆的半径,椭圆的两个半轴
* @param loc Y坐标的相对偏移量
* @param angle 旋转的角度,单位为角度
* @return 计算后的坐标值
*/
public int getY(int r, int angle, int locY)
{
int y = locY + (int) (r * ( / 180.0 * angle));
return y;
}
8.4在多线程程序中,要考虑互斥的原因是什么?在Java中如何解决?
答:多线程之间要共享资源,为了保护资源在使用时,不被其他线程使用。
在Java语言中,使用关键字synchronized定义临界段,能对共享对象的操作上锁。
8.5在多线程程序中,要考虑同步的原因是什么?在Java中如何解决?
答:在临界段中使用wait()方法,使执行该方法的线程等待,并允许其他线程使用这个
临界段。wait()方法常用以下两种格式:
wait(),让线程一直等待,直到被notify()或notifyAll()方法唤醒。
wait(long timeout),让线程等待到被唤醒,或经过指定时间后结束等待。
当线程使用完临界段后,用notify()方法通知由于想使用这个临界段而处于等待的线程
结束等待。notify()方法只是通知第一个处于等待的线程。如果某个线程在使用完临界段方
法后,其他早先等待的线程都可结束等待,重新竞争CPU,则可以notifyAll()方法。
8.6模拟排队买票,球票5元,购票者持有5,10,20,50元的,售票员手里开
始没有零钱。
程序运行结果:
21
主窗体源文件:
import .*;
import .*;
import .*;
/**
* 8.6 线程实现,购票规则,由于我想的算法太过复杂,只写到50元面值的
* @author 段智敏
*/
public class BuyTicketFrame extends JFrame implements ActionListener,
Runnable
{
private static final long serialVersionUID = 1L;
private Conductor lady;
private int array[] = { 10, 10, 5, 20, 50, 5, 5, 5, 5, 5, 5, 10, 20,
10, 5, 10, 20, 5 };
private int number = ;
private Thread thread[] = new Thread[number];
static JTextArea text;
private JButton begin_button, replay_button;
private JPanel panel;
public BuyTicketFrame()
{
super("第八章,第六题,线程模拟购票");
lady = new Conductor(15);
text = new JTextArea();
panel = new JPanel();
begin_button = new JButton("开始买票");
replay_button = new JButton("重新开始");
for (int i = 0; i < ; i++)
thread[i] = new Thread(this);
begin_ionListener(this);
replay_ionListener(this);
out(new FlowLayout());
(begin_button);
(replay_button);
(panel, );
(new JScrollPane(text), );
e(1000, 700);
ible(true);
te();
22
dowListener(new WindowAdapter()// 窗口监视器
{
public void windowClosing(WindowEvent e)
{
(0);
}
});
}
public void actionPerformed(ActionEvent e)
{
if (rce() == begin_button)// 线程开始
{
t("********" + number + "个人排队买票,共" +
ketAmount() + "张票,开始卖票:n");
try
{
for (int i = 0; i < ; i++)
{
thread[i].start();
if (thread[i].isAlive())
(" " + (i + 1) + "线程开始n");
}
begin_eground();
}
catch( IllegalThreadStateException ee )
{
("error:重复启动线程" + ng());
}
// 检查线程是否结束
while (true)
{
int n = 0;
for (int i = 0; i < ; i++)
{
if (thread[i].isAlive())
break;
else
n++;
}
if (n == )
break;
}
begin_eground();// 全部线程结束
("n全部线程结束,已经没有排队等待买票的了");
}
if (rce() == replay_button)
{
All();
new BuyTicketFrame();
}
}
public void run()
{
for (int i = 0; i < ; i++)
{
if (tThread() == thread[i])
(i + 1, array[i]);
}
23
}
}
public static void main(String args[])
{
new BuyTicketFrame();
}
售票员类源文件:
/**
* 售票员
* @author 段智敏
*/
class Conductor
{
/** 售票员开始持有的各种钞票的数量 */
private int five = 0, ten = 0, twenty = 0, fifty = 0;
/** 总的票数 */
private int ticket_amount;
/**
* 构造方法
* @param number - 票的初始数
*/
public Conductor(int number)
{
_amount = number;
}
public int getTicketAmount()
{
return ticket_amount;
}
/**
* 买票规则方法
*/
public synchronized void rule(int index, int money)
{
if (ticket_amount <= 0)
{
(index + "************售票结束
**********n");
return;
}
if (money == 5)
fiveGive(index);
if (money == 10)
tenGive(index);
if (money == 20)
twentyGive(index);
if (money == 50)
fiftyGive(index);
.append("--------------------------------------------------------
-----------------------");
("剩余票数:" + ticket_amount + "张:¥:
24
5元:" + five + "张;10元:" + ten
+ "张;20元:" + twenty + "张;50元:" + fifty + "张n");
notifyAll();// 唤醒所以线程
}
public void fiveGive(int index)
{
if (ticket_amount <= 0)
{
(index + "************售票结束
**********n");
return;
}
else
{
five++;
ticket_amount--;
("第" + index + "个,5快的,钱正好,
给你票n");
}
}
public void tenGive(int index)// 10元找钱规则
{
while (true)
{
if (five >= 1)
break;
else
{
("第" + index + "个,10元,找不
开,发...生...等...待...☆☆☆☆☆n");
try
{
wait();
}
catch( InterruptedException e )
{
}
}
}
if (ticket_amount <= 0)
{
(index + "************售票结束
**********n");
return;
}
else
{
ticket_amount--;
five--;
ten++;
("第" + index + "个,10元的,找你5
元的,给你票n");
}
}
25
public void twentyGive(int index)// 20元找钱规则
{
while (true)
{
if (((five >= 1 && ten >= 1) || five >= 3))// 20元的两种找钱
规则:3*5,10+5
break;// 跳出while循环,意味着有符合的规则
else
{
("第" + index + "个,20元,找不
开,发...生...等...待...☆☆☆☆☆n");
try
{
wait();
}
catch( InterruptedException e )
{
}
}
}
if (ticket_amount <= 0)
{
(index + "************售票结束
**********n");
return;
}
else if (ten >= 1 && five >= 1)// 20元找钱规则:10+5
{
ticket_amount--;
five--;
ten--;
twenty++;
("第" + index + "个,20元的,找你1
个5元,1个10块的,给你票n");
return;
}
else if (five >= 3)// 20元找钱规则:5*3
{
ticket_amount--;
five -= 3;
twenty++;
("第" + index + "个,20元的,找你3
个5元的,给你票n");
}
}
public void fiftyGive(int index)// 50元,找钱规则
{
while (true)
{
if ((twenty >= 2 && five >= 1) || (twenty >= 1 && ten >= 2 &&
five >= 1)
|| (twenty >= 1 && ten >= 1 && five >= 3) || (ten >=
4 && five >= 1)
|| (ten >= 3 && five >= 3) || (ten >= 2 && five >= 5)
26
|| (ten >= 1 && five >= 7) || (five >= 9))
break;// 50元的8种找钱方法
else
{
("第" + index + "个,50元,找不
开,发...生...等...待...☆☆☆☆☆n");
try
{
wait();
}
catch( InterruptedException e )
{
}
}
}
// 跳出while循环后,符合照片规则
if (ticket_amount <= 0)
{
(index + "************售票结束
**********n");
return;
}
// 先可20的先找,然后在10元的
else if (twenty >= 2 && five >= 1)// 50元找钱规则1:20*2+5
{
ticket_amount--;
five--;
twenty -= 2;
fifty++;
("第" + index + "个,50元的,找你2
个20,1个5元的,给你票n");
return;
}
else if (twenty >= 1 && ten >= 2 && five >= 1)// 50元找钱规则2:
20+10*2+5
{
ticket_amount--;
twenty--;
ten -= 2;
five--;
fifty++;
("第" + index + "个,50元的,找你1
个20,2个10,1个5元的,给你票n");
return;
}
else if (twenty >= 1 && ten >= 1 && five >= 3)// 50元找钱规则3:
20+10+5*3
{
ticket_amount--;
twenty--;
ten--;
five -= 3;
fifty++;
("第" + index + "个,50元的,找你1
个20,1个10,1个5元的,给你票n");
return;
}
else if (ten >= 4 && five >= 1)// 50元找钱规则4:10*4+5
{
27
ticket_amount--;
ten -= 4;
five -= 1;
fifty++;
("第" + index + "个,50元的,找你4
个10,1个5元的,给你票n");
return;
}
else if (ten >= 3 && five >= 3)// 50元找钱规则5:10*3+5*3
{
ticket_amount--;
ten -= 3;
five -= 3;
fifty++;
("第" + index + "个,50元的,找你3
个10,3个5元的,给你票n");
return;
}
else if (ten >= 2 && five >= 5)// 50元找钱规则6:10*2+5*5
{
ticket_amount--;
ten -= 2;
five -= 5;
fifty++;
("第" + index + "个,50元的,找你2
个10,5个5元的,给你票n");
return;
}
else if (ten >= 1 && five >= 7)// 50元找钱规则7:10+5*7
{
ticket_amount--;
ten--;
five -= 7;
fifty++;
("第" + index + "个,50元的,找你1
个10,7个5元的,给你票n");
return;
}
else if (five >= 9)// 50元找钱规则8:5*9
{
ticket_amount--;
five -= 9;
fifty++;
("第" + index + "个,50元的,找你9
个5元的,给你票n");
}
}
}
8.7修改例8.5程序,使一些暂时找不到零钱等待的顾客能按照先来先买的规则,
排队等待购买纪念品。
程序运行结果:
28
主窗口类:
import .*;
import .*;
import .*;
/**
* 排队买票,主窗口类
* @author 段智敏
*
*/
public class MainFrame extends JFrame implements ActionListener
{
private static final long serialVersionUID = 1L;
/** 19个顾客的信息,名字,和钱 */
private String name[] = { "A", "B", "C", "D", "E", "F", "G", "H", "I",
"J", "K", "L", "M", "N",
"O", "P", "Q", "R", "S" };
private int moneies[] = { 10, 10, 5, 10, 5, 10, 5, 5, 10, 5, 10, 5,
5, 10, 5, 10, 5, 5, 5 };
private Customer[] customer;
private SalesLady lady;
/** 显示信息的文本区,显示售票员信息,和队伍信息 */
private JTextArea text1, text2;
/** 开始按钮 */
private JButton start_button;
/** 布局用的panel */
private JPanel panel1, panel2;
public MainFrame()
{
super("多线程 - 排队 - 买票");
customer = new Customer[];
lady = new SalesLady();
text1 = new JTextArea();
text2 = new JTextArea();
start_button = new JButton("开始演示");
panel1 = new JPanel();
panel2 = new JPanel();
xtArea(text1, text2);
start_ionListener(this);
der(TitledBorder("信息栏"));
29
out(new GridLayout(1, 2, 10, 10));
(new JScrollPane(text1));
(new JScrollPane(text2));
(start_button);
nds(50, 50, 550, 400);
(panel1, );
(panel2, );
ible(true);
te();
dowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
(0);
}
});
}
public void actionPerformed(ActionEvent e)
{
start_bled(false);
();
for (int i = 0; i < ; i++)
{
customer[i] = new Customer(name[i], moneies[i], lady);// 创
建消费者
customer[i].start();
}
}
public static void main(String args[])
{
new MainFrame();
}
}
售货员类源文件:
import rea;
/**
* 售货员类
*/
public class SalesLady extends Thread
{
private int mem, five, ten; // 纪念品数,5、10元RMB张数
private LinkQueue queue;// 链队列
private boolean state;// 用来让线程结束的
private JTextArea text1, text2;
private int amount;// 用来确定线程的结束
public SalesLady(int length)
{
= length;
mem = 20;
five = 0;
ten = 0;
state = true;
queue = new LinkQueue();
}
30
/**
* 构造方法
* @param m - 纪念品数
* @param f - 5元数量
* @param t - 10元数量
* @param l - 人数
*/
public SalesLady(int m, int f, int t, int l)
{
= m;
= f;
= t;
= l;
state = true;
queue = new LinkQueue();
}
/**
* 排队,入队列
* @param obj
*/
public synchronized void stand_in_a_line(Object obj)
{
e(obj);
(ng() + "来排队了,此时队伍:" +
ueue() + "n");
}
public void run()
{
while (state)
{
if (amount == 0)
break;
if (!yQueue())
{
try
{
Customer cus = (Customer) ue();
(ng() + "在队头,所以去买票并出队,
此时队伍:" + ueue()
+ "n");
(ruleForSale(cus));
}
catch( Exception e )
{
tackTrace();
}
}
}
("售货员:没人排队了,我下班了");
}
/**
31
* 卖票规则方法
* @param num - 顾客号
* @param money - 顾客给的钱
* @return - 购买信息
*/
public String ruleForSale(Customer cust)
{
String message = "";
int money = ey();
String name = tomerName();
if (mem == 0)
{
state = false;
message = "售货员:对不起,纪念币已经卖完!n";// 结束方法
}
else if (money == 5)
{
mem--;
five++;
amount--;
message = "售货员:顾客-" + name + ",成功购买1个纪念品,你的钱正
好.n";
}
else if (money == 10)
{
if (five < 1)
{
stand_in_a_line(cust);
message = ("售货员:顾客-" + name + ",用10元买物品,没有零钱,
请去重新排队," + name + "很无奈的去排队了n");
}
else
{
mem--;
five--;
ten++;
amount--;
message = "售货员:顾客-" + name + ",成功购买1个纪念品,你给
我10块,我找你5块!n";
}
}
return message;
}
public void setJTextArea(JTextArea text1, JTextArea text2)
{
1 = text1;
2 = text2;
}
}
顾客类源文件:
/**
* 顾客类
*/
public class Customer extends Thread
{
private String name;
private int money;
32
}
private SalesLady lady;
public Customer(String name, int money, SalesLady lady)
{
super(name);
= name;
= money;
= lady;
}
/**
* 得到顾客排队序号
* @return - 序号
*/
public String getCustomerName()
{
return ;
}
/**
* 得到顾客付的钱数
* @return - 钱
*/
public int getMoney()
{
return ;
}
public String toString()
{
return ;
}
public void run()
{
try
{
_in_a_line(this);
(10);
}
catch( InterruptedException e )
{
}
}
链队列类源文件:
/**
* 队列的链式存储
* @author 段智敏
*/
public class LinkQueue
{
/** 队列头 */
private Node front;
/** 队列尾 */
private Node rear;
public LinkQueue()
{
33
Node p = new Node();
front = p;
rear = p;
}
/**
* 入队列操作
* @param obj - 要入队的数据
*/
public void enQueue(Object obj)
{
Node p = new Node(obj);// 数据位obj,next为null的节点
t(p);// 队尾的next为p,把p连接到队列上
= p;// p变成队尾
}
/**
* 出队列操作
* @return 返回以出队列的节点的数据
* @throws Exception
*/
public Object outQueue() throws Exception
{
if (isEmptyQueue())
throw new Exception("error:队列为空,不能操作!");
else
{
Object obj;
Node s = t();
obj = a();
t(t());// 删掉头结点后面的节点,所以front的
next 等于
// 他后面的节点的next
if (t() == null)// 如果此时front的下个节点为空,则
出队后,队列就空
rear = front;
return obj;
}
}
/**
* 判断队列是否为空
* @return 为空,返回真,不为空,返回假
*/
public boolean isEmptyQueue()
{
if (front == rear)
return true;
else
return false;
}
/**
* 得到队头元素
* @return 返回队头元素的数据
* @throws Exception
*/
public Object getHeadData() throws Exception
34
}
{
if (isEmptyQueue())
throw new Exception("error:队列为空,不能操作!");
else
{
return t().getData();
}
}
/**
* 得到队头的引用
* @return 返回队头元素的引用
* @throws Exception
*/
public Node getHeadNode() throws Exception
{
if (isEmptyQueue())
throw new Exception("error:队列为空,不能操作!");
else
{
return front;
}
}
/**
* 打印出队列的所有元素
*/
public String printQueue()
{
String result = "";
Node p = t();
while (p != null)
{
result += (a().toString() + " ");
p = t();
}
return result;
}
链式存储结点类源文件:
package 8_7;
/**
* 链式存储时候,用的结点类
*/
public class Node
{
/** 此结点的后继结点的引用 */
private Node next;
/** 此结点的数据 */
private Object data;
/**
* 无参数构造方法,后继引用和数据都为null
*/
public Node()
{
= null;
35
= null;
}
/**
* 直接设置此结点数据的构造方法
* @param obj - 该结点的数据
*/
public Node(Object obj)
{
= null;
= obj;
}
/**
* 同时设置该结点的后继结点,和数据
* @param obj - 该结点的数据
* @param next - 该结点的后继结点的引用
*/
public Node(Object obj, Node next)
{
= next;
= obj;
}
/**
* 设置后继结点的引用
* @param n - 该结点的后继结点
*/
public void setNext(Node n)
{
= n;
}
/**
* 得到其后继结点的引用
* @return 返回结点引用
*/
public Node getNext()
{
return next;
}
/**
* 设置其数据
* @param obj - 数据
*/
public void setData(Object obj)
{
= obj;
}
/**
* 得到数据,object类型
* @return 返回数据
*/
public Object getData()
{
return ;
}
36
}
/**
* 得到此数据的字符串形式
*/
public String toString()
{
return ng();
}
37
版权声明:本文标题:《Java语言程序设计》考试练习题(带答案)三 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://roclinux.cn/p/1735624293a1682149.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论