即使线程终止,锁也不会释放

时间:2018-07-23 16:18:15

标签: java concurrency reentrantlock

在以下程序中,该程序不会以某种方式结束。当我进行调试时,在检查dateTimeChange变量期间显示该锁是由Producer线程持有的,如下所示

  

java.util.concurrent.locks.ReentrantLock@55584367 [被线程锁定   池1线程1]   java.util.concurrent.locks.ReentrantLock$NonfairSync@5b9fb7bc [状态=   8,空队列]

lock

以下是结果:

public class LocksTest {

    public static void main(String[] args) {
        List<String> contents = new ArrayList<>();
        Lock lock = new ReentrantLock();
        String greenColor = "\u001B[32m";
        String yellowColor = "\u001B[33m";
        String redColor = "\u001B[31m";
        MyProducer myProducer = new MyProducer(greenColor, contents, lock);
        MyConsumer myConsumer1 = new MyConsumer(yellowColor, contents, lock);
        MyConsumer myConsumer2 = new MyConsumer(redColor, contents, lock);

        ExecutorService service = Executors.newFixedThreadPool(3);
        service.execute(myProducer);
        service.execute(myConsumer2);
        service.execute(myConsumer1);
// new Thread(myProducer).start();
// new Thread(myConsumer1).start();
// new Thread(myConsumer2).start();
        service.shutdown();
    }
}

class MyProducer implements Runnable {

    private String color;
    private List<String> contents;
    private Lock lock;

    public MyProducer(String color,
                      List<String> contents,
                      Lock lock) {
        this.color = color;
        this.contents = contents;
        this.lock = lock;
    }

    @Override
    public void run() {

        int count = 0;
        while (true) {
            if (lock.tryLock()) {
                try {
                    contents.add("" + ++count);
                    System.out.println(color + "Adding " + count);
                    if (count == 5) {
                        System.out.println(color + "Adding " + "EOF");
                        contents.add("EOF");
                        break;
                    }

                    try {
                        Thread.sleep(1000l);
                    } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace();
                    }

                } finally {
                    lock.unlock();
                }
            }
        }
    }
}

class MyConsumer implements Runnable {

    private String color;
    private List<String> contents;
    private Lock lock;

    public MyConsumer(String color,
                      List<String> contents,
                      Lock lock) {
        this.color = color;
        this.contents = contents;
        this.lock = lock;
    }

    @Override
    public void run() {
        String value = null;
        while (true) {
            if (lock.tryLock()) {
                try {
                    if (!contents.isEmpty()) {
                        Iterator<String> stringItr = contents.iterator();

                        while (stringItr.hasNext())
                            value = stringItr.next();
                        System.out.println(color + "Consuming " + value);
                        stringItr.remove();
                    }
                    if ("EOF".equals(value)) {
                        break;
                    }
                } finally {
                    lock.unlock();
                }
            }
        }
    }
}

[32mAdding 1
[33mConsuming 1
[32mAdding 2
[33mConsuming 2
[32mAdding 3
[33mConsuming 3
[32mAdding 4
[33mConsuming 4
[32mAdding 5
[32mAdding EOF
[33mConsuming EOF
[31mConsuming 5

虽然结果符合预期,但我不确定为什么程序不会终止?其次,终止的线程是否可以保留[32mAdding 1 [32mAdding 2 [32mAdding 3 [32mAdding 4 [32mAdding 5 [32mAdding EOF [33mConsuming EOF [31mConsuming 5 [31mConsuming 4 [31mConsuming 3 [31mConsuming 2 [31mConsuming 1 (我观察到这种使用注释的传统线程使用方式的奇怪行为)?!

1 个答案:

答案 0 :(得分:3)

好吧,消费者和生产者共享锁对我来说有点奇怪,但是您的问题是生产者放了一个 EOF ,而您有2个消费者。因此,消费者(而非您的生产者)无法打破while循环。