简体   繁体   中英

LinkedBlockingQueue and write locks in java

i am a neophyte in java concurrency and wanted to know when to use a LinkedBlockingQueue. Say there is an upload servlet. There can be concurrent uploads. When the file is being written, we are currently using:

 // Used for synchronising a small portion of code
 private final Object writeLock  = new Object();

and in the code where the file is actually written to the filesystem,

 if (!file.exists()){
        synchronized(writeLock){
            fileItem.write( file ); 
        }               
 }

This works fine, well, so far it has worked.. i am keen to know when/how to use a BlockingQueue to solve this issue or is a BlockingQueue required in the first place when we can use Object locks.

BlockingQueue is useful whenever you have a producer-consumer situation. Instead of having to handle locking explicitly, the class takes care of thread-safety for you and provides a clear and useful interface.

In your case, it's not clear what you're needing to protect from simultaneous access; are you wanting to ensure that you don't have filename collisions? If so, you need to synchronize the whole snippet including the if statement, and BlockingQueue doesn't really help you much (you couldn't write multiple files simultaneously).

Using a BlockingQueue allows you to do without the synchronized block around the write operation. Servlet applications are inherently multi-threaded. You have multiple threads waiting to serve HTTP requests. The synchronized keyword ensures that only one thread can process the code block at a time.

With a BlockingQueue, you would create a new thread that would act as a consumer for data. The servlet threads would act as producers for that data. Only the single consumer thread would handle writing the files. The BlockingQueue would ensure that consumer requests for writes are buffered. The consumer thread and all the producer threads need a reference to the same BlockingQueue.

The general logic is like this.

Consumer:

while( true ) {
    final Item item = queue.take(); // This blocks until an item is placed on the queue.
    item.write( file );
}

Producer:

queue.put( item ); // put this in your servlet method

Note that I omitted important details such as handling interruptions and spawning the consumer thread. See the documentation for more details: http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/BlockingQueue.html .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM