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。尝试获取锁时未锁定。我修正了锁的顺序。我考虑过阻塞队列,但我想处理尽可能多的对象,这就是为什么我选择使用锁和条件。