一、
1.如果线程死亡,它便不能运行。(T)
2.在Java中,高优先级的可运行线程会抢占低优先级线程。(T)
3.线程可以用yield方法使低优先级的线程运行。(F)
4...程序开发者必须创建一个线程去管理内存的分配。(F)//Java提供了一个系统线程来管理分配内存
5.一个线程在调用它的start方法,之前,该线程将一直处于出生期。(T)
6.当调用一个正在进行线程的stop( )方法时,该线程便会进入休眠状态。(F)
7.一个线程可以调用yield方法使其他线程有机会运行。(T)
8. 多线程没有安全问题(F)
9. 多线程安全问题的解决方案可以使用Lock提供的具体的锁对象操作(T)
10. Stop()方法是终止当前线程的一种状态()
二、选择题(不定项选择题),每题2分
1.Java语言中提供了一个▁线程,自动回收动态分配的内存。
A.异步
B.消费者
C.守护
D.垃圾收集
2.Java语言避免了大多数的▁错误。
A.数组下标越界
B.算术溢出
C.内存泄露
D.非法的方法参数
3.有三种原因可以导致线程不能运行,它们是▁。
A.等待
B.阻塞
C.休眠
D.挂起及由于I/O操作而阻塞
4.当▁方法终止时,能使线程进入死亡状态。
A.run
B.setPrority//更改线程优先级
C.yield//暂停当前线程的执行 执行其他线程
D.sleep//线程休眠
5.用▁方法可以改变线程的优先级。
A.run
B.setPrority
C.yield
D.sleep
6.线程通过▁▁方法可以使具有相同优先级线程获得处理器。
A.run
B.setPrority
C.yield
D.sleep
7.线程通过▁▁方法可以休眠一段时间,然后恢复运行。
A.run
B.setPrority
C.yield
D.sleep
8.方法resume( )负责重新开始▁▁线程的执行。
A.被stop( )方法停止
B.被sleep( )方法停止
C.被wait( )方法停止
D.被suspend( )方法停止
9.▁▁方法可以用来暂时停止当前线程的运行。
A.stop( )
B.sleep( )
C.wait( )
D.suspend( )
10. 请问下列哪些类是定义在java.io包中的抽象类(ABCD)
A. InputStream
B. OutputStream
C. PrintStream
D. Reader
E. FileInputStream
F. FileWriter
三、简述题,每题5分
1.简述程序、进程和线程之间的关系?什么是多线程程序?
程序:指令的有序集合,由它规定计算机完成某一任务时所需做的各种操作及操作顺序
进程:一个可并发执行的具有独立功能的程序关于某个数据集合的一次执行过程,是操作系统进行资源分配调度的基本单位(简单来说就是一个正在运行的程序)
线程:线程依赖于进程而存在,一个线程相当于进程中的某个任务。
多线程:是多个线程同时在执行。这些线程的执行是并发的,在逻辑上是同时进行,各个线程的控制流彼此独立。
3.什么是线程调度?Java的线程调度采用什么策略?
线程调度:按照特定机制为多个线程分配CPU的使用权
java 的调度策略是基于线程优先级的抢先式调度。意思就是,谁的优先级高那我就先给谁使用系统资源。比如说,当前正在运行一个优先级为5的线程,这个时候来了一个优先级为8的线程,那么系统就会把当前运行的线程挂起,去运行这个优先级高的线程,一直等到这个优先级高的线程运行完毕才会继续运行它。如果说来的也是一个优先级为5的线程,那么他们两个就是轮流使用系统资源,谁也不用让谁。
4.如何在Java程序中实现多线程?
继承Thread类:class MyThread extends Thread
实现Runnable接口:class MyThread implements Runnable
创建线程池对象:实现Callable接口
5.试简述Thread类的子类或实现Runnable接口两种方法的异同?
继承的方式具有局限性,实现接口更符合java的设计原则以及设计模式,数据分离原则,MyRunnable的对象作为两个子线程的共有对象(共享数据),接口的方式比继承的方式多
6. 说明缓冲流的优点和原理
使用缓冲流的好处是,能够更高效的读写信息,原理是将数据先缓冲起来,然后一起写入或者读取出来。
8:在Java中wait()和sleep()方法的不同?
相同点:阻塞式
不同:wait()线程等待,调用会立即释放锁
sleep()线程睡眠,调用不会释放锁
9:Java中Runnable和Callable有什么不同?
(1)Callable规定的方法是call(),Runnable规定的方法是run().
(2)Callable的任务执行后可返回值,而Runnable的任务是不能返回值得
(3)call方法可以抛出异常,run方法不可以
(4)运行Callable任务可以拿到一个Future对象,Future 表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并获取计算的结果。计算完成后只能使用 get 方法来获取结果,如果线程没有执行完,Future.get()方法可能会阻塞当前线程的执行;如果线程出现异常,Future.get()会throws InterruptedException或者ExecutionException;如果线程已经取消,会跑出CancellationException。取消由cancel 方法来执行。isDone确定任务是正常完成还是被取消了。一旦计算完成,就不能再取消计算。如果为了可取消性而使用 Future 但又不提供可用的结果,则可以声明Future> 形式类型、并返回 null 作为底层任务的结果。
四、程序设计题
package lastwaitnotify;
public class Student {
private String name;
private int age;
//声明一个变量
private boolean flag; //默认没有数据,如果是true,则说明有数据
//set(String name,int age)方法,产生数据
//同步机制可以解决数据不一致
public synchronized void set(String name,int age){
//等待唤醒机制
//判断有没有数据
if(this.flag){
//处于等待状态
try {
this.wait();//阻塞方式,立即释放锁 notify
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//设置学生数据
this.name = name;
this.age = age;
//修改标记
this.flag = true;//有数据
//通知gt:消费者线程来消费
this.notify();//唤醒等待状态
}
//get()输出数据
public synchronized void get(){
if(!this.flag){
try {
this.wait() ;//调用的时候,会立即释放锁
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//输出语句
System.out.println(this.name+"---"+this.age);
//修改标记
this.flag = false ;//消费者线程
//通知对方(st线程),消费者线程没有数据类,赶紧来消费
this.notify() ;//唤醒t1线程....
}
}
package lastwaitnotify;
//生产者线程
public class SetThread implements Runnable{
private Student s;
public SetThread(Student s){
this.s = s;
}
private int i = 0;
@Override
public void run() {
while(true){
if(i%2==0){
//设置学生数据
s.set("韩庚", 18);
}else{
//设置学生数据
s.set("张靓颖", 16);
}
i++;
}
}
}
package lastwaitnotify;
public class GetThread implements Runnable{
private Student s;
public GetThread(Student s){
this.s = s;
}
@Override
public void run() {
while(true){
s.get();
}
}
}
测试类
package lastwaitnotify;
public class StudentDemo {
public static void main(String[] args) {
// 创建资源对象
Student s = new Student();
//创建资源对象
SetThread st = new SetThread(s);
GetThread gt = new GetThread(s);
//创建线程类对象
Thread t1 = new Thread(st);
Thread t2 = new Thread(gt);
//分别启动线程
t1.start();
t2.start();
}
}
3. 1)将若干个Student对象;若干个Teacher对象,写出到d:/0404/a.txt中,
2)将该文件中所有的Student对象反序列化回来,装入List,所有的Teacher对象反序列化回来装入另一个List
package file;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
/**
*1.将若干个Student对象;若干个Teacher对象,写出到d:/0404/a.txt中,
*2.将该文件中所有的Student对象反序列化回来,装入List,所有的Teacher对象反序列化回来装入另一个List
*
*2017年12月8日
*/
public class homeworktest4 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//创建文件夹
File file = new File("d:\\0404");
file.mkdir();
//创建文件
File file1 = new File("d:\\0404\\a.txt");
file1.createNewFile();
//序列化
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file1));
//public final void writeObject(Object obj):将obj对象写入到当前的序列化流中
oos.writeObject(new Student("张三",33));
oos.writeObject(new Student("王五",55));
oos.writeObject(new Teacher("小李",66));
oos.writeObject(new Teacher("小赵",22));
oos.flush();
//反序列化
ObjectInputStream ois=new ObjectInputStream(new FileInputStream(file1));
ArrayList listStu=new ArrayList();
ArrayList listTea=new ArrayList();
for(int i=0;i<4;i++){
if(i<2){
Student s=(Student)ois.readObject();
listStu.add(s);
}else{
Teacher t=(Teacher)ois.readObject();
listTea.add(t);}
}
//}
for(Student s : listStu){
System.out.println(s);
}
for(Teacher t : listTea){
System.out.println(t);
}
//释放资源
oos.close();
ois.close();
}
}
package file;
import java.io.Serializable;
//学生类
public class Student implements Serializable{
private static final long serialVersionUID = 2L;
private String name;
private int age;
public Student() {
super();
}
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
}
package file;
import java.io.Serializable;
//教师类
public class Teacher implements Serializable{
private static final long serialVersionUID = 2L;
private String name;
private int age;
public Teacher() {
super();
}
public Teacher(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Teacher [name=" + name + ", age=" + age + "]";
}
}
4:实现字符串和字节数组之间的相互转换,比如:将字符串”西部开源技术中心xbkyjszx”转换为字节数组,并将字节数组再转换回字符串!
package homework4;
import java.util.Arrays;
import java.util.Scanner;
public class StringToByte {
public static void main(String[] args) {
// 创建键盘录入对象
Scanner sc = new Scanner(System.in);
//录入并输入数据
System.out.println("请输入一个字符串:");
String str = sc.nextLine();
//字符串转换成字符数组
byte[] bys = str.getBytes();
System.out.print(Arrays.toString(bys) + " ");
System.out.println();
//字符数组再转成字符串
String str1 = new String(bys);
System.out.println(str1);
}
}
5:用Java编程一个会导致死锁的程序,你将怎么解决?请你设计
package dielock;
public class DieLock extends Thread{
//定义一个成员变量
private boolean flag;
//有参构造方法
public DieLock(boolean flag){
this.flag = flag;
}
@Override
public void run() {
// d1、d2线程
if(flag){
synchronized(MyLock.objA){
System.out.println("if objA");
synchronized(MyLock.objB){
System.out.println("if objB");
}
}
}else{
//d1、d2
synchronized(MyLock.objB){
System.out.println("else objB");
synchronized(MyLock.objA){
System.out.println("else objA");
}
}
}
}
}
package dielock;
public class MyLock {
//创建两把锁对象
public static final Object objA = new Object();
public static final Object objB = new Object();
}
package dielock;
public class DieLockDemo {
public static void main(String[] args) {
// 创建线程类对象
DieLock d1 = new DieLock(true);
DieLock d2 = new DieLock(false);
//启动线程
d1.start();
d2.start();
}
}
6.
递归实现输入任意目录,
列出文件以及文件夹
package homework6;
import java.io.File;
import java.util.Scanner;
public class Homework6 {
public static void main(String[] args) {
//创建键盘录入对象
Scanner sc = new Scanner(System.in);
//键盘录入文件名
System.out.println("请输入任意路径:");
File strFolder = new File(sc.nextLine());
print(strFolder);
}
private static void print(File strFolder) {
//判断文件是否存在
if(strFolder!=null){
//文件存在,判断是否是文件夹
if(strFolder.isDirectory()){
//是文件夹,获取文件夹所有文件
File[] fileArray = strFolder.listFiles();
if(fileArray!=null){
for (int i = 0; i < fileArray.length; i++) {
print(fileArray[i]);
}
}
}else{
System.out.println(strFolder);
}
}
}
}