我刚刚开始在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。
答案 0 :(得分:0)
您实际上是通过使用lock和tryLock在threa.run中获得了4次锁定,并且仅释放了一次。更糟糕的是:您在释放它之后立即将其重新锁定。这意味着在第一个线程完成后,锁将保持锁定状态。
由于您的SynchronizedInt已经使用了synced关键字,因此您甚至不需要在这里锁定。而且,您甚至不需要syncedInt类,只需使用内置的AtomicInt。