实验内容:
源代码:



package exercise;
public class ArrayIndexOutOfBoundsException {
	public static void main(String args[]) {
		int a[] = null;							//定义数组,初始化为null
		a = new int[5];							//设置数组大小
		System.out.println("程序开始运行");			//程序开始运行
		try {
			for (int i = 1; i < 10; i++) {				//使数组越界
				a[i - 1] = i - 2;
			}
		} catch (Exception e) {							//异常类型匹配
			System.out.println(e);						
			System.out.println("数组越界");				//输出类型
		} finally {
			System.out.println("程序正常结束");				//程序正常结束
		}

	}
}


运行截图:
实验思路:因为以前遇到过数组越界的问题,实验要实现这个问题还是比较简单的,主要自己给出异常的处理方法就好了。

源代码:


package exercise;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

class DangerEexception extends Exception {
	String massage = null;
	public DangerException() {
		massage = "bibibi 危险物品:";
	}
	public String toshow() {
		return massage;
	}
}
class Goods {
	String name;
	boolean isDanger = true;

	public Goods(String name) {
		this.name = name;
	}
}
public class Machine {
	static ArrayList list;

	public Machine(ArrayList list) {
		this.list = list;
	}

	public void ListAdd(String name) {
		list.add(name);
	}

	public void ListRemove(String name) {
		if (list != null) {
			list.remove(name);
		}
	}

	void cheakBag(Goods goods) throws Myexception {
		if (goods.isDanger) {
			throw new Myexception();
		}

	}

	public static void main(String args[]) {
		String n = null;
		int flag = 0;
		list = new ArrayList();
		Machine machine = new Machine(list); 
		Goods goods = new Goods(n);
		machine.ListAdd("打火机");      //添加初始危险物品
		machine.ListAdd("管制刀具");
		machine.ListAdd("汽油");
		machine.ListAdd("化妆品");
		Scanner sc = new Scanner(System.in);
		System.out.println("1.添加危險物品");
		System.out.println("2.刪除危險物品");
		System.out.println("3.物品檢查");
		System.out.print("请输入操作类型:");
		flag = sc.nextInt();
		if (flag == 1) {
			System.out.print("请输入添加的物品:" + " ");
			String x = sc.next();
			machine.ListAdd(x);
			System.out.println("开始检查:");
			System.out.print("待检查物品:" + " ");
			n = sc.next();
			if (list.contains(n)) {
				try {
					machine.cheakBag(goods);
				} catch (Myexception e) {
					System.out.println(e.toshow() + n);
				}

			} else {
				System.out.println("安全通过");
			}
		}
		if (flag == 2) {
			System.out.print("请输入删除的物品:" + " ");
			String x = sc.next();
			machine.ListRemove(x);
			System.out.println("开始检查:");
			System.out.print("待检查物品:" + " ");
			n = sc.next();
			if (list.contains(n)) {
				try {
					machine.cheakBag(goods);
				} catch (Myexception e) {
					System.out.println(e.toshow() + n);
				}

			} else {
				System.out.println("安全通过");
			}
		}
		if (flag == 3) {
			System.out.println("开始检查:");
			System.out.print("待检查物品:" + " ");
			n = sc.next();
			if (list.contains(n)) {
				try {
					machine.cheakBag(goods);
				} catch (Myexception e) {
					System.out.println(e.toshow() + n);
				}

			} else {
				System.out.println("安全通过");
			}
		}
	}
}


运行截图:
添加:

删除:

检查:

感想:这个题目老师上课说过,但是在我拿到题目的时候,就有点看不懂了,我到现在为止还是不知道goods有什么用,如果是只是用来确定isDanger为true的话,那么完全可以定义为String name而不是Goods goods,然后定义的Goods类,也只是存了一个name和一个isDanger,== 有点不明白,应该是知识水平过低,不过还是基本上实现了这个题目的要求。还有在使用ArrayList类时,刚开始我是直接实例化的一个list队列,然后list.add()添加,list.remove()删除,然后想了想,要求好像要可以添加,然后就修改了,直接定义了一个ArrayList lsit属性,就可以实现用户添加和删除了,在代码的最后面,那个flag判断,emm,代码有点多余,不过还是自己慢慢优化吧,因为我觉得问题有点麻烦,然后需要在思考一下再进行修改,还是因为技术不行,得加强训练。

学习总结:
一个线程的生命周期:

新建状态:
使用 new 关键字和 Thread 类或其子类建立一个线程对象后,该线程对象就处于新建状态。它保持这个状态直到程序 start() 这个线程。

就绪状态:
当线程对象调用了start()方法之后,该线程就进入就绪状态。就绪状态的线程处于就绪队列中,要等待JVM里线程调度器的调度。

运行状态:
如果就绪状态的线程获取 CPU 资源,就可以执行 run(),此时线程便处于运行状态。处于运行状态的线程最为复杂,它可以变为阻塞状态、就绪状态和死亡状态。

阻塞状态:
如果一个线程执行了sleep(睡眠)、suspend(挂起)等方法,失去所占用资源之后,该线程就从运行状态进入阻塞状态。在睡眠时间已到或获得设备资源后可以重新进入就绪状态。可以分为三种:

等待阻塞:运行状态中的线程执行 wait() 方法,使线程进入到等待阻塞状态。

同步阻塞:线程在获取 synchronized 同步锁失败(因为同步锁被其他线程占用)。

其他阻塞:通过调用线程的 sleep() 或 join() 发出了 I/O 请求时,线程就会进入到阻塞状态。当sleep() 状态超时,join() 等待线程终止或超时,或者 I/O 处理完毕,线程重新转入就绪状态。

死亡状态:
一个运行状态的线程完成任务或者其他终止条件发生时,该线程就切换到终止状态。

线程的优先级
每一个 Java 线程都有一个优先级,这样有助于操作系统确定线程的调度顺序。

Java 线程的优先级是一个整数,其取值范围是 1 (Thread.MIN_PRIORITY ) - 10 (Thread.MAX_PRIORITY )。

默认情况下,每一个线程都会分配一个优先级 NORM_PRIORITY(5)。

具有较高优先级的线程对程序更重要,并且应该在低优先级的线程之前分配处理器资源。但是,线程优先级不能保证线程执行的顺序,而且非常依赖于平台。
创建一个线程
Java 提供了三种创建线程的方法:

通过实现 Runnable 接口;
通过继承 Thread 类本身;
通过 Callable 和 Future 创建线程
Thread 方法
下表列出了Thread类的一些重要方法:

序号 方法描述
1 public void start()使该线程开始执行;Java 虚拟机调用该线程的 run 方法。
2 public void run()如果该线程是使用独立的 Runnable 运行对象构造的,则调用该 Runnable 对象的 run 方法;否则,该方法不执行任何操作并返回。
3 public final void setName(String name) 改变线程名称,使之与参数 name 相同。
4 public final void setPriority(int priority) 更改线程的优先级。
5 public final void setDaemon(boolean on) 将该线程标记为守护线程或用户线程。
6 public final void join(long millisec) 等待该线程终止的时间最长为 millis 毫秒。
7 public void interrupt() 中断线程。
8 public final boolean isAlive() 测试线程是否处于活动状态。

测试线程是否处于活动状态。 上述方法是被Thread对象调用的。下面的方法是Thread类的静态方法。

序号 方法描述
1 public static void yield() 暂停当前正在执行的线程对象,并执行其他线程。
2 public static void sleep(long millisec) 在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响。
3 public static boolean holdsLock(Object x) 当且仅当当前线程在指定的对象上保持监视器锁时,才返回 true。
4 public static Thread currentThread() 返回对当前正在执行的线程对象的引用。
5 public static void dumpStack() 将当前线程的堆栈跟踪打印至标准错误流。

创建线程的三种方式的对比

  1. 采用实现 Runnable、Callable 接口的方式创建多线程时,线程类只是实现了 Runnable 接口或 Callable 接口,还可以继承其他类。

  2. 使用继承 Thread 类的方式创建多线程时,编写简单,如果需要访问当前线程,则无需使用 Thread.currentThread() 方法,直接使用 this 即可获得当前线程。

线程的几个主要概念
在多线程编程时,你需要了解以下几个概念:

线程同步
线程间通信
线程死锁
线程控制:挂起、停止和恢复

多线程的使用

有效利用多线程的关键是理解程序是并发执行而不是串行执行的。例如:程序中有两个子系统需要并发执行,这时候就需要利用多线程编程。

通过对多线程的使用,可以编写出非常高效的程序。不过请注意,如果你创建太多的线程,程序执行的效率实际上是降低了,而不是提升了。

请记住,上下文的切换开销也很重要,如果你创建了太多的线程,CPU 花费在上下文的切换的时间将多于执行程序的时间!