java - 如何通过等待/通知编写保证死锁

标签 java multithreading concurrency deadlock wait

我最近访问了一些面试。面试官让我写保证死锁。

我写了以下内容:

public class DeadLockThreadSleep {
    private static class MyThread implements Runnable {
        private Object o1;
        private Object o2;

        @Override
        public void run() {
            try {
                test(o1, o2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        public MyThread(Object o1, Object o2) {
            this.o1 = o1;
            this.o2 = o2;
        }

        public void test(Object o1, Object o2) throws InterruptedException {
            synchronized (o1) {
                System.out.println("1.acquired: " + o1);
                Thread.sleep(1000);
                synchronized (o2) {
                    System.out.println("2.acquired: " + o2);

                }
            }
        }
    }

    public static void main(String[] args) {
        Object o1 = new Object();
        Object o2 = new Object();
        new Thread(new MyThread(o1, o2)).start();
        new Thread(new MyThread(o2, o1)).start();

    }
}

然后他问我是否确定它是有保证的。我记得 Thread.sleep 没有任何保证。

然后我写了这段代码:

public static void main(String[] args) {
        final Thread mainThread = Thread.currentThread();
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    mainThread.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        thread.start();
        try {
            thread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

这个答案被接受了。

他还要求通过等待/通知编写模拟。想了很多,想不出怎么写。

这可能吗?

最佳答案

这可以通过创建一个循环来完成,其中一个线程持有一个资源并等待另一个资源,而另一个线程以相反的顺序执行相同的操作。

线程 t 持有 resourceOne 并等待 resourceTwo ,而 t1 持有 resourceTwo 并等待 resourceOne

下面是一个示例代码:

    public class WaitNotifyLock {

        boolean isONHold = false;
        public synchronized void hold(){
            while(isONHold){
                try {
                    wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        isONHold = true;
        System.out.println(Thread.currentThread().getId() + " : Holded");
    }

    public synchronized void unHold(){
        while(!isONHold){
            try {
                wait();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        System.out.println(Thread.currentThread().getId() + " : Produced");
        isONHold = false;
        notify();
    }

    public static void main(String[] args) {
        WaitNotifyLock resourceOne =  new WaitNotifyLock();
        WaitNotifyLock resourceTwo =  new WaitNotifyLock();
        Thread t = new Thread(new Runnable() {

            @Override
            public void run() {
                // TODO Auto-generated method stub
                resourceOne.hold();
                try {
                    Thread.sleep(2);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                resourceTwo.hold();
                resourceOne.unHold();
                resourceTwo.unHold();
            }
        });

        Thread t1 = new Thread(new Runnable() {

            @Override
            public void run() {
                resourceTwo.hold();
                try {
                    Thread.sleep(2);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                        e.printStackTrace();
                }
                resourceOne.hold();
                resourceTwo.unHold();
                resourceOne.unHold();
                }
            });

            t.start();
            t1.start();
        }

    }

关于java - 如何通过等待/通知编写保证死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41440845/

相关文章:

java - 使用 java Runtime.getRunTime.exec() 的交互式命令

java - 显示不匹配的字符串,正则表达式否定

multithreading - 在 S3 存储桶之间并行移动文件

google-apps-script - 如何为 Google Apps Script Webapp 上的并发用户提供便利?

java - Maven 或不 Maven

c# - 通过 COM 或直接集成到 Java 中使用 .Net 库

c++ - 两个线程共享变量 C++

winapi - 在线程中,如果设置为INFINITE,则WaitForMultipleObjects永远不会返回

java - Spring 安全出版

concurrency - 了解 Rob Pike 的图书焚烧示例