Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/320.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

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,我在一些简单的生产者/消费者(并基于正确的示例)代码中获得了互锁线程 有一个线程执行以下操作: public void append(final Object obj) { buffer.add(obj); if (buffer.size() >= BUFFER_MAX_SIZE) { insertLock.lock(); switchLock.lock(); insertLo

我在一些简单的生产者/消费者(并基于正确的示例)代码中获得了互锁线程

有一个线程执行以下操作:

    public void append(final Object obj) {
        buffer.add(obj);

        if (buffer.size() >= BUFFER_MAX_SIZE) {
            insertLock.lock();
            switchLock.lock();
            insertLock.unlock();

            bufferFull.signal();
            try {
                bufferSwitch.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            switchLock.unlock();
        }
    }
有另一个线程使用此代码:

        try {
            insertLock.lock();
            while (true) {
                switchLock.lock();
                insertLock.unlock();
                bufferFull.await();
                switchBuffers();
                bufferSwitch.signal();
                insertLock.lock();
                switchLock.unlock();

                if (insertBuffer.size() > 0) {
                    db.insert(insertBuffer);
                    insertBuffer.clear();
                }
            }
        } catch (InterruptedException e) {
                e.printStackTrace();
        }
正如我提到的,它基于条件API文档中的生产者/消费者示例。我无法检测到为什么两个线程都被困在条件等待方法上

有什么错误吗?看起来有些东西是我肉眼看不见的

谢谢,

PS:添加了工作代码。

线程A没有

        insertLock.lock();
        switchLock.lock();
而线程B确实如此

        switchLock.lock();
        ....
        insertLock.lock();
因此,如果线程A获取
插入锁
,而线程B获取
开关锁
,那么A和B都不能进入下一行。

这是一种基本情况。您应该始终确保锁的锁定顺序相同

对于线程的生产者/消费者问题,您可以查看java提供的接口及其派生类

例如:

package cl.mds.migracion;

import java.util.concurrent.ArrayBlockingQueue;

public class Example {

    static ArrayBlockingQueue<String> buffer = new ArrayBlockingQueue<String>(5);

    static class Producer  implements Runnable{

        @Override
        public void run() {
            for (int i = 0; i < 10; i++){
                try {
                    Thread.sleep(500); //seleep 500ms to simulate producer time
                    buffer.put(String.valueOf(i)); //put waits the thread until there is size in the queue.
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    static class Consumer implements Runnable{

        public void run() {
            for (int i = 0; i < 10; i++){
                try {
                    Thread.sleep(100); //seleep 100ms to simulate slower consumer tha producer
                    System.out.printf("Consuming %s ....%n",buffer.take()); //take waits the thread until there is something in the queue
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    public static void main(String[] args){
        System.out.printf("Starting producer/consumer ....%n");
        new Thread(new Producer()).start();
        new Thread(new Consumer()).start();
        System.out.printf("Finishing ....%n");
    }
}
包cl.mds.migracion;
导入java.util.concurrent.ArrayBlockingQueue;
公开课范例{
静态ArrayBlockingQueue缓冲区=新的ArrayBlockingQueue(5);
静态类生成器实现Runnable{
@凌驾
公开募捐{
对于(int i=0;i<10;i++){
试一试{
Thread.sleep(500);//选择500毫秒以模拟生产者时间
buffer.put(String.valueOf(i));//put等待线程,直到队列中有大小。
}捕捉(中断异常e){
e、 printStackTrace();
}
}
}
}
静态类使用者实现可运行{
公开募捐{
对于(int i=0;i<10;i++){
试一试{
Thread.sleep(100);//选择100毫秒以模拟较慢的消费程序
System.out.printf(“正在使用%s….%n”,buffer.take());//take等待线程,直到队列中有东西
}捕捉(中断异常e){
e、 printStackTrace();
}
}
}
}
公共静态void main(字符串[]args){
System.out.printf(“起始生产者/消费者….%n”);
新线程(新生产者()).start();
新线程(新使用者()).start();
System.out.printf(“精加工…%n”);
}
}

想法是尽可能快地切换缓冲区。在生产太快的情况下,我应该确保在再次切换缓冲区之前完全插入数据。我尝试锁定插入锁以确保它没有插入数据。如果我锁定它,它不会插入数据,所以我可以继续锁定开关锁,等待完全缓冲信号。在这种情况下,我的误解是,在run方法到达fullbufferwait之前,从append数据发送信号通知fullbuffer。尝试获取锁时未锁定。我修正了锁的顺序。我考虑过阻塞队列,但我想处理尽可能多的对象,这就是为什么我选择使用锁和条件。