Java线程等待唤醒机制

记录面试过程中被问到的几个需要手写代码的小案例

1.请手写出线程的等待唤醒机制

案例中两个线程:SyncSetThread设置学生信息,SyncGetThread用来获取学生信息,在Student实体中提供一个标记属性flag,记录当前是否有数据。


等待唤醒机制
  • 设置信息线程SyncSetThread
/*
 * 使用Object的wait() 和 notify() 来实现等待唤醒机制
 * Created by JackYang on 2017/10/17.
 */

class SyncSetThread implements Runnable {

    private final Student student;

    SyncSetThread(Student student) {
        this.student = student;
    }

    @Override
    public void run() {
        int num = 0;
        while (true) {
            synchronized (student) {
                if (student.flag) {
                    try {
                        student.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                if (num % 2 == 0) {
                    student.name = "JackYang";
                    student.age = 26;
                } else {
                    student.name = "江一燕";
                    student.age = 28;
                }
                ++num;
                student.flag = true;
                student.notify();
                //此时唤醒,SyncSetThread和SyncGetThread两个线程都有同等的机会去抢占资源
            }
        }
    }
}
  • 获取信息线程SyncGetThread
class SyncGetThread implements Runnable {

    private final Student student;

    SyncGetThread(Student student) {
        this.student = student;
    }

    @Override
    public void run() {
        while (true) {
            synchronized (student) {

                if (!student.flag) {
                    try {
                        //对象中没有数据的时候就等待
                        student.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

                System.out.println(student.name + "---" + student.age);
                //数据消费完了(取出后)改变标记
                student.flag = false;
                student.notify();
                //此时唤醒,SyncSetThread和SyncGetThread两个线程都有同等的机会去抢占资源
            }
        }
    }
}
  • 测试入口
/*
 * 线程的等待唤醒机制,实现一人一次有规律
 * Created by JackYang on 2017/10/17.
 */

public class TestSyncThread {
    public static void main(String[] args) {

        Student student = new Student();

        SyncSetThread syncSetThread = new SyncSetThread(student);
        SyncGetThread syncGetThread = new SyncGetThread(student);

        Thread thread1 = new Thread(syncSetThread);
        Thread thread2 = new Thread(syncGetThread);

        thread1.start();
        thread2.start();
    }
}

2.请手写出线程死锁代码

这个没得商量,直接上代码

/**
 * 死锁代码
 * Created by JackYang on 2017/10/17.
 */

class DieThread extends Thread {

    private boolean flag;

    DieThread(boolean flag) {
        this.flag = flag;
    }

    @Override
    public void run() {

        if (flag) {
            //防止一次卡不住
            while (true) {
                synchronized (MyLock.lockA) {
                    System.out.println("true lockA");
                    synchronized (MyLock.lockB) {
                        System.out.println("true lockB");
                    }
                }
            }

        } else {

            while (true) {
                synchronized (MyLock.lockB) {
                    System.out.println("false lockB");
                    synchronized (MyLock.lockA) {
                        System.out.println("false lockA");
                    }
                }
            }
        }
    }
}

你可能感兴趣的:(Java线程等待唤醒机制)