Java重入锁:第二个线程无法获得锁

时间:2018-08-06 06:54:28

标签: java multithreading reentrantlock

我刚刚开始在Java中使用同步方法,并制作了一个使用可重入锁的基本应用程序

这是应该执行的操作: 一个线程将通过锁定来首先访问锁定的类,以防止发生冲突。一旦第一个线程完成增量,那么第二个线程将执行相同的操作。

我的问题是,在解锁之后,第一个线程说它已经解锁,而第二个线程仍然会处于锁定状态,这意味着它处于饥饿状态。

这是我的代码

主班

public class JavaApplication3 {
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
        SynchronizedInt s = new SynchronizedInt();
        Thread t1 = new Thread(new FlameThread(s));
        Thread t2 = new Thread(new FlameThread(s));
            t1.start();
            t2.start();
    }
}

锁类

public class SynchronizedInt {
    private int count;
    private Lock l;

    public SynchronizedInt() {
        this.count = 0;
        this.l = new ReentrantLock();
    }

    public synchronized void addCounter() {
        this.count++;
        ThreadMessage.print(Integer.toString(this.count));
    }

    public synchronized Lock getLock() {
        return l;
    }
}

线程类

public class FlameThread implements Runnable {
    private SynchronizedInt s;

    public FlameThread(SynchronizedInt s) {
        this.s = s;
    }
    @Override
    public void run() {
        while(true){
            try {
                try{
                    while(!this.s.getLock().tryLock()){
                        ThreadMessage.print(""+this.s.getLock().tryLock());
                        Thread.sleep(1000);
                    }
                    this.s.getLock().lock();
                    this.s.addCounter();
                }finally{
                    this.s.getLock().unlock();
                }
                ThreadMessage.print(""+this.s.getLock().tryLock());
                Thread.sleep(1000);
            } catch (InterruptedException ex) {
                Logger.getLogger(FlameThread.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }
}

ThreadMessage

public class ThreadMessage {
    // Display a message, preceded by
    // the name of the current thread
    public static void print(String message) {
        String threadName = Thread.currentThread().getName();
        System.out.format("%s: %s%n", threadName, message);
    }
}

结果

run:
Thread-0: 1
Thread-0: true
Thread-1: false
Thread-0: 2
Thread-1: false
Thread-0: true
Thread-0: 3
Thread-1: false
Thread-0: true
Thread-0: 4
Thread-1: false
Thread-0: true

编辑#1:

预期产量

run:
Thread-0: 1
Thread-0: true
Thread-1: false
Thread-1: 2
Thread-1: true
Thread-0: false
Thread-0: 3
Thread-0: true
Thread-1: false
...

单个线程不应占用所有锁

编辑#2:

解决了问题。

显然,我不应该使用trylock。

1 个答案:

答案 0 :(得分:0)

您实际上是通过使用lock和tryLock在threa.run中获得了4次锁定,并且仅释放了一次。更糟糕的是:您在释放它之后立即将其重新锁定。这意味着在第一个线程完成后,锁将保持锁定状态。

由于您的SynchronizedInt已经使用了synced关键字,因此您甚至不需要在这里锁定。而且,您甚至不需要syncedInt类,只需使用内置的AtomicInt。