习题12
一、问答题
1.线程有几种状态?
2.引起线程中断的常见原因是什么?
3.一个线程执行完run方法后,进入了什么状态?该线程还能再调用start方法吗?
4.线程在什么状态时,调用isAlive()方法返回的值是false。
5.建立线程有几种方法?
6.怎样设置线程的优先级?
7.在多线程中,为什么要引入同步机制?
8.在什么方法中wait()方法、notify()及notifyAll()方法可以被使用?
9.将例子6中SellTicket类中的循环条件:
while(fiveAmount<3)
该写成:
if(fiveAmount<3)
是否合理。
10.线程调用interrupt()的作用是什么?
二、选择题
1.下列哪个叙述是错误的
A.线程新建后,不调用start方法也有机会获得CPU资源
B.如果两个线程需要调用同一个同步方法,那么一个线程调用该同步方法时,另一个线程必须等待。
C.目标对象中的run方法可能不启动多次。
D.默认情况下,所有线程的优先级都是5级。
2.对于下列程序,哪个叙述是正确的?
A.JVM认为这个应用程序共有两个线程。
B.JVM认为这个应用程序只有一个主线程。
C.JVM认为这个应用程序只有一个thread线程。
D.thread的优先级是10级。
public class E {
public static void main(String args[]) {
Target target =new Target();
Thread thread =new Thread(target);
thread.start();
}
}
class Target implements Runnable{
public void run(){
System.out.println("ok");
}
}
3.对于下列程序,哪个叙述是正确的?
A.JVM认为这个应用程序共有两个线程。
B.JVM认为这个应用程序只有一个主线程。
C.JVM认为这个应用程序只有一个thread线程。
D.程序有编译错误,无法运行。
public class E {
public static void main(String args[]) {
Target target =new Target();
Thread thread =new Thread(target);
target.run();
}
}
class Target implements Runnable{
public void run(){
System.out.println("ok");
}
}
二、阅读程序
1.上机运行下列程序,注意程序的运行效果(程序有两个线程:主线程和thread线程)。
public class E {
public static void main(String args[]) {
Target target =new Target();
Thread thread =new Thread(target);
thread.start();
for(int i= 0;i<=10;i++) {
System.out.println("yes");
try{
Thread.sleep(1000);
}
catch(InterruptedException exp){}
}
}
}
class Target implements Runnable{
public void run() {
for(int i= 0;i<=10;i++) {
System.out.println("ok");
try{ Thread.sleep(1000);
}
catch(InterruptedException exp){}
}
}
}
2.上机运行下列程序,注意程序的运行效果(注意该程序中只有一个主线程,thread线程并没有启动)。
public class E {
public static void main(String args[]) {
Target target =new Target();
Thread thread =new Thread(target);
target.run();
for(int i= 0;i<=10;i++) {
System.out.println("yes");
try{ Thread.sleep(1000);
}
catch(InterruptedException exp){}
}
}
}
class Target implements Runnable{
public void run() {
for(int i= 0;i<=10;i++) {
System.out.println("ok");
try{
Thread.sleep(1000);
}
catch(InterruptedException exp){}
}
}
}
3.上机运行下列程序,注意程序的运行效果(注意程序的输出结果)。
public class E {
public static void main(String args[]) {
Target target =new Target();
Thread thread1 =new Thread(target);
Thread thread2 =new Thread(target);
thread1.start();
try{ Thread.sleep(1000);
}
catch(Exception exp){}
thread2.start();
}
}
class Target implements Runnable{
int i = 0;
public void run() {
i++;
System.out.println("i="+i);
}
}
4.上机运行下列程序,注意程序的运行效果(注意和上面习题3的不同之处)。
public class E {
public static void main(String args[]) {
Target target1 =new Target();
Target target2 =new Target();
Thread thread1 =new Thread(target1); //与thread2的目标对象不同
Thread thread2 =new Thread(target2); //与thread1的目标对象不同
thread1.start();
try{ Thread.sleep(1000);
}
catch(Exception exp){}
thread2.start();
}
}
class Target implements Runnable{
int i = 0;
public void run() {
i++;
System.out.println("i="+i);
}
}
5.上机运行下列程序,注意程序的运行效果(计时器启动成功)。
import javax.swing.*;
import java.util.Date;
public class Ex {
public static void main(String args[]) {
javax.swing.Timer time=new javax.swing.Timer(500,new A());
time.setInitialDelay(0);
time.start();
}
}
class A extends JLabel implements java.awt.event.ActionListener {
public void actionPerformed(java.awt.event.ActionEvent e){
System.out.println(new Date());
}
}
6.上机运行下列程序,注意程序的运行效果(计时器启动失败)。
import javax.swing.*;
import java.util.Date;
public class Ex {
public static void main(String args[]) {
javax.swing.Timer time=new javax.swing.Timer(500,new A());
time.setInitialDelay(0);
time.start();
}
}
class A implements java.awt.event.ActionListener {
public void actionPerformed(java.awt.event.ActionEvent e){
System.out.println(new Date());
}
}
7.在下列E类中【代码】输出结果是什么?
import java.awt.*;
import java.awt.event.*;
public class E implements Runnable {
StringBuffer buffer=new StringBuffer();
Thread t1,t2;
E() { t1=new Thread(this);
t2=new Thread(this);
}
public synchronized void addChar(char c) {
if(Thread.currentThread()==t1) {
while(buffer.length()==0) {
try{ wait();
}
catch(Exception e){}
}
buffer.append(c);
}
if(Thread.currentThread()==t2) {
buffer.append(c);
notifyAll();
}
}
public static void main(String s[]) {
E hello=new E();
hello.t1.start();
hello.t2.start();
while(hello.t1.isAlive()||hello.t2.isAlive()){}
System.out.println(hello.buffer); //【代码】
}
public void run() {
if(Thread.currentThread()==t1)
addChar('A') ;
if(Thread.currentThread()==t2)
addChar('B') ;
}
}
8.上机实习下列程序,了解同步块的作用。
public class E {
public static void main(String args[]) {
Bank b=new Bank();
b.thread1.start();
b.thread2.start();
}
}
class Bank implements Runnable {
Thread thread1,thread2;
Bank() {
thread1=new Thread(this);
thread2=new Thread(this);
}
public void run() {
printMess();
}
public void printMess() {
System.out.println(Thread.currentThread().getName()+"正在使用这个方法");
synchronized(this) { //当一个线程使用同步块时,其他线程必须等待
try { Thread.sleep(2000);
}
catch(Exception exp){}
System.out.println(Thread.currentThread().getName()+"正在使用这个同步块");
}
}
}
四、编程题
1. 参照例子8,模拟三个人排队买票,张某、李某和赵某买电影票,售票员只有三张五元的钱,电影票5元钱一张。张某拿二十元一张的新人民币排在李的前面买票,李某排在赵的前面拿一张10元的人民币买票,赵某拿一张5元的人民币买票。
2.参照例子6,要求有3个线程:student1、student2和teacher,其中student1准备睡10分钟后再开始上课,其中student2准备睡一小时后再开始上课。teacher在输出3句“上课”后,吵醒休眠的线程student1;student1被吵醒后,负责再吵醒休眠的线程student2。
3.参照例子9,编写一个Java应用程序,在主线程中再创建3个线程:“运货司机”、“装运工”和“仓库管理员”。要求线程“运货司机”占有CPU资源后立刻联合线程“装运工”,也就是让“运货司机”一直等到“装运工”完成工作才能开车,而“装运工”占有CPU资源后立刻联合线程“仓库管理员”, 也就是让“装运工”一直等到“仓库管理员”打开仓库才能开始搬运货物。