Java can synchronize of blocks of code via lock.
It's a more powerful and flexible mechanism than the synchronized keyword.
Java lock mechanism is based on the Lock
interface and classes that implement it as ReentrantLock
.
The Lock
interfaces have better performance than the synchronized keyword.
At the end of the critical section, use the unlock()
method to free the control of the lock.
This allows the other threads to run this critical section.
The tryLock()
method from Lock interface and ReentrantLock class will return a boolean value telling if the lock is gotten.
If it can't get the control, returns immediately and doesn't put the thread to sleep.
import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class Main { public static void main(String args[]) { SharedResource printQueue = new SharedResource(); Thread thread[] = new Thread[10]; for (int i = 0; i < 10; i++) { thread[i] = new Thread(new Worker(printQueue), "Thread " + i); }/*from w w w . j av a2s .com*/ for (int i = 0; i < 10; i++) { thread[i].start(); } } } class Worker implements Runnable { private SharedResource shapredResource; public Worker(SharedResource s) { this.shapredResource = s; } @Override public void run() { System.out.printf("%s: About to print a document\n", Thread.currentThread().getName()); shapredResource.doTask(new Object()); System.out.printf("%s: The document has been printed\n", Thread.currentThread().getName()); } } class SharedResource { private final Lock queueLock = new ReentrantLock(); public void doTask(Object document) { queueLock.lock(); try { Long duration = (long) (Math.random() * 10000); System.out.printf("%s: Printing a Job during %d seconds\n", Thread.currentThread().getName(), (duration / 1000)); Thread.sleep(duration); } catch (InterruptedException e) { e.printStackTrace(); } finally { queueLock.unlock(); } } }