面试题1
public class Test {
public static void main(String[] args) {
Base b = new Sub();
System.out.println(b.x);
System.out.println(b.printMessage());
}
}
class Base {
int x = 10;
public Base() {
// this.printMessage();
System.out.println("Base.x = " + this.x);
x = 20;
}
public int printMessage() {
System.out.println("Base.x = " + x);
return 1;
}
}
class Sub extends Base {
int x = 30;
public Sub() {
// this.printMessage();
System.out.println("Base.x = " + this.x);
x = 40;
}
public int printMessage() {
System.out.println("Sub.x = " + x);
return 1;
}
}
//Base.x = 10
//Base.x = 30
//20
//Sub.x = 40
//1
1. 父类中静态成员变量和静态代码块
2. 子类中静态成员变量和静态代码块
3. 父类中普通成员变量和代码块,父类的构造函数
4. 子类中普通成员变量和代码块,子类的构造函数
其中“和”字两端的按照代码先后顺序执行。
this在调用方法的时候, 指的是调用者本身;
this在调用属性的时候,指的是当前类对象。
/* * 堆栈 * */ public class Test2 { private List<String> list = new ArrayList<String>(); public synchronized void push(String value) { synchronized (this) { list.add(value); notify(); } } public synchronized String pop() throws InterruptedException { synchronized (this) { if (list.size() <= 0) { wait(); } return list.remove(list.size() - 1); } } }
问题: 这段代码大多数情况下运行正常,但是某些情况下会出问题。什么时候会出现什么问题?如何修正?
case1:删除不存在的元素
假设现在有三个线程A、B、C,其中A用于添加元素,B、C用于删除元素。
某时刻,栈为空,
step1、线程B运行,获取锁,list.size()=0,进入wait(),wait状态下会释放当前锁
step2、线程A运行,获取锁,添加元素,执行list.add(value),此时list.size()=1,注意:在A执行notify()之前,线程C启动,发现其他线程已经拥有对象锁,因此进入阻塞状态,等待锁
step3、线程A执行notify(),试图唤醒等待中的线程B,但是但是但是,如果此时C获取了对象锁,那么将优先执行,那么C判断list.size()=1,直接删除元素,然后释放对象锁
step4、wait状态下的B获取对象锁,直接执行list.remove(list.size()-1),发生错误!!!
解决办法: 最小代码改动,就在remove之前再检查list.size==0。
synchronized (this) {}是加锁的意思。