面试题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) {}是加锁的意思。

posted @ 2017-08-31 15:11  夏末阳光Flo  阅读(104)  评论(0编辑  收藏  举报