📜  门| GATE CS 2008 |问题5(1)

📅  最后修改于: 2023-12-03 14:58:19.197000             🧑  作者: Mango

门 | GATE CS 2008 | 问题5

这是GATE CS 2008年的问题5,是一道关于多线程编程的问题。以下是问题描述:

有一个类Door,其中包含两个方法open()和close()。你需要编写一个多线程程序,使得Door的open()和close()方法可以同时被多个线程调用,但不能同时被两个线程调用。

要求:

  • 使用Java中的Lock或Semaphore进行同步
  • 保证open()和close()方法的互斥访问
  • 能够处理InterruptedException异常
  • 代码应该能够正确运行,并会在资源释放之后正常终止。

以下是解决这道问题的代码片段:

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Door {
    private Lock lock = new ReentrantLock(); // 创建一个可重入锁

    public void open() throws InterruptedException {
        lock.lock(); // 获取锁
        try {
            // 执行需要同步的代码
            System.out.println("Door opened");
        } finally {
            lock.unlock(); // 释放锁
        }
    }

    public void close() throws InterruptedException {
        lock.lock(); // 获取锁
        try {
            // 执行需要同步的代码
            System.out.println("Door closed");
        } finally {
            lock.unlock(); // 释放锁
        }
    }
}

public class Main {
    public static void main(String[] args) {
        Door door = new Door(); // 创建Door实例

        // 创建并启动线程A
        Thread threadA = new Thread(() -> {
            try {
                door.open();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        threadA.start();

        // 创建并启动线程B
        Thread threadB = new Thread(() -> {
            try {
                door.close();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        threadB.start();

        // 等待两个线程结束
        try {
            threadA.join();
            threadB.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

代码中我们创建了一个可重入锁,并在open()和close()方法中分别使用lock()方法获取锁,使用unlock()方法释放锁。使用可重入锁可以保证同一个线程如果多次调用open()或close()方法,也只会获得一次锁。这可以避免死锁的问题。

在main()方法中创建了两个线程A和B,并分别调用door的open()和close()方法。使用join()方法可以保证在两个线程结束之后,程序才会退出。

这段代码可以满足问题的所有要求,能够正确地同步open()和close()方法的访问。