Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么锁不传递给另一个线程_Java_Multithreading - Fatal编程技术网

Java 为什么锁不传递给另一个线程

Java 为什么锁不传递给另一个线程,java,multithreading,Java,Multithreading,当缓冲区队列为空时,在通知第一个线程激活并运行剩余代码后,线程正在等待另一个线程进入缓冲区队列中的元素,但只有一个在缓冲区队列中接收输入的线程处于活动状态,而另一个线程不工作。我认为线程通知不起作用 Main.java LRUManager.java Input.java 您的输入线程永远不会退出方法同步,因此永远不会释放锁。Notify告诉LRU线程退出等待状态,但它随后会让线程被阻塞,等待永远不会到达的锁 您需要的是inputController()中notifyAll()之后的wait()

当缓冲区队列为空时,在通知第一个线程激活并运行剩余代码后,线程正在等待另一个线程进入缓冲区队列中的元素,但只有一个在缓冲区队列中接收输入的线程处于活动状态,而另一个线程不工作。我认为线程通知不起作用

Main.java

LRUManager.java

Input.java


您的输入线程永远不会退出方法同步,因此永远不会释放锁。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