思维导图
Java专题(当天的,后续下篇补充
每日要点
线程相关
线程暂停(进入对象等待池)
parcels.wait();
wait()操作会释放对象的锁
在等待池中的线程需要其他线程将其唤醒
唤醒所有在等待池中等待parcels对象的线程
线程从等待池进入等锁池(等锁池中的线程要抢占到对象锁以后才能进入就绪态)
parcels.notifyAll();
设置优先级改变的是线程获得CPU调度的几率
但是在抢占对象锁的时候优先级高的线程并没有优势
wang.setPriority(Thread.MAX_PRIORITY);
例子1.快递员送货
// 快递员
class DeliveryMan {
private String name; // 名字
private ParcelCenter parcelCenter; // 包裹中心
public DeliveryMan(String name, ParcelCenter parcelCenter) {
this.name = name;
this.parcelCenter = parcelCenter;
}
// 送快递
public void send() {
List<String> parcels = parcelCenter.getParcels();
synchronized (parcels) {
// 如果包裹中心没有需要送出的包裹就等待(线程暂停)
if (parcels.isEmpty()) {
try {
parcels.wait(); // 线程暂停(进入对象等待池)
// wait()操作会释放对象的锁
// 在等待池中的线程需要其他线程将其唤醒
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
// 随机取走若干个包裹并送出
int number = (int) (Math.random() * parcels.size());
for (int i = 0; i < number; i++) {
String parcel = parcels.remove(0);
System.out.println(name + "正在送" + parcel);
}
}
}
}
// 包裹中心
class ParcelCenter {
private long id = 1; // 包裹单号
private List<String> parcels = new ArrayList<>(); // 装所有包裹的容器
public List<String> getParcels() {
return parcels;
}
// 生成需要送出的包裹
public void generateParcels() {
String[] names = {"鲜花", "牛奶", "外卖", "信件"};
// 随机生成1-5件包裹
int number = (int) (Math.random() * 5 + 1);
synchronized (parcels) {
for (int i = 0; i < number; i++) {
parcels.add("单号[" + id + "]: "
+ names[(int) (Math.random() * names.length)]);
id += 1;
}
// 唤醒所有在等待池中等待parcels对象的线程
// 线程从等待池进入等锁池(等锁池中的线程要抢占到对象锁以后才能进入就绪态)
parcels.notifyAll(); // 通知快递员已经有包裹可以送出了
}
}
}
class Test02 {
public static void main(String[] args) {
ParcelCenter center = new ParcelCenter();
DeliveryMan man1 = new DeliveryMan("王大锤", center);
DeliveryMan man2 = new DeliveryMan("李莫愁", center);
// 包裹中心每隔3秒钟产生若干需要送出的包裹
new Thread(() -> {
while (true) {
try {
Thread.sleep(3000);
}
catch (InterruptedException e) {
}
center.generateParcels();
}
}).start();
// 快递员持续送出包裹
Thread wang = new Thread(() -> {
while (true) {
man1.send();
}
});
// 设置优先级改变的是线程获得CPU调度的几率
// 但是在抢占对象锁的时候优先级高的线程并没有优势
wang.setPriority(Thread.MAX_PRIORITY);
wang.start();
new Thread(() -> {
while (true) {
man2.send();
}
}).start();
}
}
深度克隆和浅克隆
例子:
package com.jack;
import java.io.Serializable;
@SuppressWarnings("serial")
class Car implements Serializable{
private String brand;
private int maxSpeed;
public Car(String brand, int maxSpeed) {
this.brand = brand;
this.maxSpeed = maxSpeed;
}
public void setBrand(String brand) {
this.brand = brand;
}
public void setMaxSpeed(int maxSpeed) {
this.maxSpeed = maxSpeed;
}
@Override
public String toString() {
return "Car=[" + brand + ", " + maxSpeed + "]";
}
}
@SuppressWarnings("serial")
class Student implements /*Cloneable 浅克隆 */ Serializable{
private String name;
private int age;
private Car car;
public Student(String name, int age, Car car) {
this.name = name;
this.age = age;
this.car = car;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public Car getCar() {
return car;
}
/* @Override
public Object clone() {
Student temp = null;
try {
temp = (Student) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return temp;
}*/
@Override
public String toString() {
return name + ", " + age + ", " + car.toString();
}
}
class Test01 {
public static void main(String[] args) {
Car car = new Car("QQ", 120);
Student s1 = new Student("王大锤", 18, car);
// Student s2 = (Student) s1.clone();
// 深度克隆
Student s2 = MyUtil.deepClone(s1);
s2.setName("小白");
s2.getCar().setBrand("Benz");
s2.getCar().setMaxSpeed(240);
System.out.println(s1);
}
}
运行时异常和非受检异常
Exception
- RuntimeException - 运行时异常(非受检异常)
- ArithmeticException
- NegativeArraySizeException
- IndexOutOfBoundsException
- IllegalMonitorStateException
- NullPointerException
- ClassCastException
- 其他 - 受检异常 - 编译器强制要求处理
- IOException
- FileNotFoundException
- ClassNotFoundException
- InterruptedException
- CloneNotSupportedException
- SQLException
例子:
// System.out.println(3 / 0);
// int[] a = new int[-3];
// a[100] = 1000;
// String str = null;
// str.toLowerCase();
例子
1.面试题:做一个在内存拷贝的深度克隆方法
public class MyUtil {
@SuppressWarnings("unchecked")
public static <T extends Serializable> T deepClone(T object) {
T temp = null;
try {
// 将对象序列化到内存流中
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(object);
// 从内存流中反序列化对象
byte[] buf = baos.toByteArray();
ByteArrayInputStream bais = new ByteArrayInputStream(buf);
ObjectInputStream ois = new ObjectInputStream(bais);
temp = (T) ois.readObject();
} catch (Exception e) {
e.printStackTrace();
}
return temp;
}
}