Java 为什么锁不传递给另一个线程
当缓冲区队列为空时,在通知第一个线程激活并运行剩余代码后,线程正在等待另一个线程进入缓冲区队列中的元素,但只有一个在缓冲区队列中接收输入的线程处于活动状态,而另一个线程不工作。我认为线程通知不起作用 Main.java LRUManager.java Input.javaJava 为什么锁不传递给另一个线程,java,multithreading,Java,Multithreading,当缓冲区队列为空时,在通知第一个线程激活并运行剩余代码后,线程正在等待另一个线程进入缓冲区队列中的元素,但只有一个在缓冲区队列中接收输入的线程处于活动状态,而另一个线程不工作。我认为线程通知不起作用 Main.java LRUManager.java Input.java 您的输入线程永远不会退出方法同步,因此永远不会释放锁。Notify告诉LRU线程退出等待状态,但它随后会让线程被阻塞,等待永远不会到达的锁 您需要的是inputController()中notifyAll()之后的wait()
您的输入线程永远不会退出方法同步,因此永远不会释放锁。Notify告诉LRU线程退出等待状态,但它随后会让线程被阻塞,等待永远不会到达的锁 您需要的是inputController()中notifyAll()之后的wait(),以及lruController()中notifyAll()之前的wait 有关示例,请参阅 还可以从else块外部的lruController()进行递归调用。
您还可以将线程内的递归调用更改为调用inputController()或lruController(),而不是直接运行。为什么有两个线程运行相同的
LRUManager
?整个设计看起来很奇怪,缓存管理器处理输入或缓存,具体取决于线程的名称。lruController()方法的第一个if中不需要额外的run()吗?否则,LRUCache线程将在第一次check@DavidLilljegren我试过了,但仍然不起作用一个不相关的问题是您正在从lruController()
和inputController()
(几乎)无条件地调用run()
。通过在调用中嵌套调用,最终会导致堆栈溢出。你需要一个循环。在inputController()
中,如果抛出InterruptedException
,您甚至不会退出。建议的行为是将中断视为“停止!”指令和退出。
public class Main {
public static void main(String[] args) throws InterruptedException {
LRUManager lruManager = new LRUManager();
Thread input = new Thread(lruManager);
Thread lruCache = new Thread(lruManager);
input.setName("Input");
lruCache.setName("LRUCache");
input.start();
lruCache.start();
}
}
public class LRUManager implements Runnable {
LRUCache lruCache = new LRUCache();
Input input = new Input();
@Override
public void run() {
String threadName = Thread.currentThread().getName();
System.out.println("ThreadName:" + threadName);
if (threadName.equalsIgnoreCase("Input")) {
inputController();
} else if (threadName.equalsIgnoreCase("LRUCache")) {
lruController();
}
}
synchronized private void lruController() {
if (input.checkbufferQueue()) {
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else {
int page = input.getinput();
lruCache.addPage(page);
lruCache.display();
run();
}
}
synchronized private void inputController() {
input.takeInput();
input.printQueue();
notifyAll();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
run();
}
}
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class Input {
Scanner scanner = new Scanner(System.in);
int page;
Queue<Integer> bufferQueue = new LinkedList<Integer>();
void takeInput() {
System.out.println("Please enter Page in the cache");
page = scanner.nextInt();
bufferQueue.add(page);
}
int getinput() {
int page = bufferQueue.poll();
return page;
}
boolean checkbufferQueue()
{
return bufferQueue.isEmpty();
}
void printQueue() {
System.out.print("bufferQueue: ");
for(int page: bufferQueue) {
System.out.print(page+" ");
}
System.out.println("\n");
}
}
import java.util.Deque;
import java.util.Iterator;
import java.util.LinkedList;
public class LRUCache {
static Deque<Integer> cache = new LinkedList<Integer>();
Input input = new Input();
private int cacheSize = 4;
int page;
void addPage(int page) {
if (!cache.contains(page)) {
if (cache.size() == cacheSize) {
cache.removeLast();
}
} else {
cache.remove(page);
}
cache.push(page);
}
public void display() {
Iterator<Integer> itr = cache.iterator();
while (itr.hasNext()) {
System.out.print(itr.next() + " ");
}
System.out.print("\n");
}
}
ThreadName:LRUCache
ThreadName:Input
Please enter Page in the cache
1
bufferQueue: 1
ThreadName:Input
Please enter Page in the cache
2
bufferQueue: 1 2
ThreadName:Input
Please enter Page in the cache
3
bufferQueue: 1 2 3
ThreadName:Input
Please enter Page in the cache
4
bufferQueue: 1 2 3 4
ThreadName:Input
Please enter Page in the cache
5
bufferQueue: 1 2 3 4 5
ThreadName:Input
Please enter Page in the cache