Lock
It's like a synchronization block,
java.util.concurrent.locks.Lock Is the thread synchronization mechanism. However, locks are more flexible and complex than synchronous blocks. Because lock is an interface, you need to use one of its implementations to use lock in your application. ReentrantLock is one such implementation of the lock interface.
Lock lock = new ReentrantLock(); lock.lock(); lock.unlock();
Differences between Lock and synchronized
1. Lock can set timeout, while synchronized cannot.
Lock.tryLock(long timeout, TimeUnit timeUnit)
2.synchronized must be in the same method. lock() and unlock() can be in different methods.
Use case of Lock
In this example, the program simulates the behavior of printing. You can submit multiple print jobs to print tasks at different intervals or at the same time. The printer takes a job from the print queue and prints it. The rest of the work will be waiting there. Once the printer has completed the print job at hand, it selects another job from the queue and starts printing. Keep the cycle going.
public class PrinterQueue { private final Lock queueLock = new ReentrantLock(); public void printJob(Object document) { queueLock.lock(); try { long duration = new Random().nextInt(10000); System.out.println(Thread.currentThread().getName() + ": PrintQueue: Printing a Job during " + (duration / 1000) + " seconds :: Time - " + new Date()); Thread.sleep(duration); } catch (InterruptedException e) { e.printStackTrace(); } finally { queueLock.unlock(); System.out.printf("%s: The document has been printedn", Thread.currentThread().getName()); } } } class PrintingJob implements Runnable { private PrinterQueue printerQueue; public PrintingJob(PrinterQueue printerQueue) { this.printerQueue = printerQueue; } @Override public void run() { System.out.printf("%s: Going to print a documentn", Thread.currentThread().getName()); printerQueue.printJob(new Object()); } }
test
public class PrinterQueue { private final Lock queueLock = new ReentrantLock(); public void printJob(Object document) { queueLock.lock(); try { long duration = new Random().nextInt(10000); System.out.println(Thread.currentThread().getName() + ": PrintQueue: Printing a Job during " + (duration / 1000) + " seconds :: Time - " + new Date()); Thread.sleep(duration); } catch (InterruptedException e) { e.printStackTrace(); } finally { queueLock.unlock(); System.out.printf("%s: The document has been printedn", Thread.currentThread().getName()); } }
effect
"D:Program FilesJavajdk1.8.0_221binjava.exe" -Dvisualvm.id=15276093588700 "-javaagent:D:Program FilesJetBrainsToolboxappsIDEA-Uch-0201.6668.121libidea_rt.jar=53022:D:Program FilesJetBrainsToolboxappsIDEA-Uch-0201.6668.121bin" -Dfile.encoding=UTF-8 -classpath "D:Program FilesJavajdk1.8.0_221jrelibcharsets.jar;D:Program FilesJavajdk1.8.0_221jrelibdeploy.jar;D:Program FilesJavajdk1.8.0_221jrelibextaccess-bridge-64.jar;D:Program FilesJavajdk1.8.0_221jrelibextcldrdata.jar;D:Program FilesJavajdk1.8.0_221jrelibextdnsns.jar;D:Program FilesJavajdk1.8.0_221jrelibextjaccess.jar;D:Program FilesJavajdk1.8.0_221jrelibextjfxrt.jar;D:Program FilesJavajdk1.8.0_221jrelibextlocaledata.jar;D:Program FilesJavajdk1.8.0_221jrelibextnashorn.jar;D:Program FilesJavajdk1.8.0_221jrelibextsunec.jar;D:Program FilesJavajdk1.8.0_221jrelibextsunjce_provider.jar;D:Program FilesJavajdk1.8.0_221jrelibextsunmscapi.jar;D:Program FilesJavajdk1.8.0_221jrelibextsunpkcs11.jar;D:Program FilesJavajdk1.8.0_221jrelibextzipfs.jar;D:Program FilesJavajdk1.8.0_221jrelibjavaws.jar;D:Program FilesJavajdk1.8.0_221jrelibjce.jar;D:Program FilesJavajdk1.8.0_221jrelibjfr.jar;D:Program FilesJavajdk1.8.0_221jrelibjfxswt.jar;D:Program FilesJavajdk1.8.0_221jrelibjsse.jar;D:Program FilesJavajdk1.8.0_221jrelibmanagement-agent.jar;D:Program FilesJavajdk1.8.0_221jrelibplugin.jar;D:Program FilesJavajdk1.8.0_221jrelibresources.jar;D:Program FilesJavajdk1.8.0_221jrelibrt.jar;D:workspaceoschinajava-study-demojdk8Demotargetclasses;D:workRepositoryeubitwalkerUserAgentUtils1.19UserAgentUtils-1.19.jar;D:workRepositorydom4jdom4j1.6.1dom4j-1.6.1.jar;D:workRepositoryxml-apisxml-apis1.0.b2xml-apis-1.0.b2.jar;D:workRepositorymysqlmysql-connector-java5.1.40mysql-connector-java-5.1.40.jar;D:workRepositoryorgapachestormstorm-hdfs1.1.0storm-hdfs-1.1.0.jar;D:workRepositoryorgapachehadoophadoop-client2.6.1hadoop-client-2.6.1.jar;D:workRepositoryorgapachehadoophadoop-mapreduce-client-app2.6.1hadoop-mapreduce-client-app-2.6.1.jar;D:workRepositoryorgapachehadoophadoop-mapreduce-client-common2.6.1hadoop-mapreduce-client-common-2.6.1.jar;D:workRepositoryorgapachehadoophadoop-yarn-client2.6.1hadoop-yarn-client-2.6.1.jar;D:workRepositoryorgapachehadoophadoop-yarn-server-common2.6.1hadoop-yarn-server-common-2.6.1.jar;D:workRepositoryorgapachehadoophadoop-mapreduce-client-shuffle2.6.1hadoop-mapreduce-client-shuffle-2.6.1.jar;D:workRepositoryorgfusesourceleveldbjnileveldbjni-all1.8leveldbjni-all-1.8.jar;D:workRepositoryorgapachehadoophadoop-yarn-api2.6.1hadoop-yarn-api-2.6.1.jar;D:workRepositoryorgapachehadoophadoop-mapreduce-client-core2.6.1hadoop-mapreduce-client-core-2.6.1.jar;D:workRepositoryorgapachehadoophadoop-yarn-common2.6.1hadoop-yarn-common-2.6.1.jar;D:workRepositoryjavaxxmlbindjaxb-api2.2.2jaxb-api-2.2.2.jar;D:workRepositoryjavaxxmlstreamstax-api1.0-2stax-api-1.0-2.jar;D:workRepositoryjavaxactivationactivation1.1activation-1.1.jar;D:workRepositorycomsunjerseyjersey-client1.9jersey-client-1.9.jar;D:workRepositoryorgapachehadoophadoop-mapreduce-client-jobclient2.6.1hadoop-mapreduce-client-jobclient-2.6.1.jar;D:workRepositoryorgapachehadoophadoop-annotations2.6.1hadoop-annotations-2.6.1.jar;D:workRepositoryorgyamlsnakeyaml1.11snakeyaml-1.11.jar;D:workRepositoryorgapachehadoophadoop-hdfs2.6.1hadoop-hdfs-2.6.1.jar;D:workRepositoryorgmortbayjettyjetty6.1.26jetty-6.1.26.jar;D:workRepositoryorgmortbayjettyjetty-util6.1.26jetty-util-6.1.26.jar;D:workRepositorycomsunjerseyjersey-core1.9jersey-core-1.9.jar;D:workRepositorycomsunjerseyjersey-server1.9jersey-server-1.9.jar;D:workRepositoryasmasm3.1asm-3.1.jar;D:workRepositorycommons-clicommons-cli1.2commons-cli-1.2.jar;D:workRepositorycommons-iocommons-io2.4commons-io-2.4.jar;D:workRepositorycommons-langcommons-lang2.6commons-lang-2.6.jar;D:workRepositorycommons-daemoncommons-daemon1.0.13commons-daemon-1.0.13.jar;D:workRepositoryjavaxservletjspjsp-api2.1jsp-api-2.1.jar;D:workRepositorylog4jlog4j1.2.17log4j-1.2.17.jar;D:workRepositorycomgoogleprotobufprotobuf-java2.5.0protobuf-java-2.5.0.jar;D:workRepositoryjavaxservletservlet-api2.5servlet-api-2.5.jar;D:workRepositoryorgcodehausjacksonjackson-core-asl1.9.13jackson-core-asl-1.9.13.jar;D:workRepositoryorgcodehausjacksonjackson-mapper-asl1.9.13jackson-mapper-asl-1.9.13.jar;D:workRepositorytomcatjasper-runtime5.5.23jasper-runtime-5.5.23.jar;D:workRepositoryxmlencxmlenc0.52xmlenc-0.52.jar;D:workRepositoryionettynetty3.6.2.Finalnetty-3.6.2.Final.jar;D:workRepositoryxercesxercesImpl2.9.1xercesImpl-2.9.1.jar;D:workRepositoryorghtracehtrace-core3.0.4htrace-core-3.0.4.jar;D:workRepositoryorgapachehadoophadoop-common2.6.1hadoop-common-2.6.1.jar;D:workRepositoryorgapachecommonscommons-math33.1.1commons-math3-3.1.1.jar;D:workRepositorycommons-httpclientcommons-httpclient3.1commons-httpclient-3.1.jar;D:workRepositorycommons-netcommons-net3.1commons-net-3.1.jar;D:workRepositorycomsunjerseyjersey-json1.9jersey-json-1.9.jar;D:workRepositoryorgcodehausjettisonjettison1.1jettison-1.1.jar;D:workRepositorycomsunxmlbindjaxb-impl2.2.3-1jaxb-impl-2.2.3-1.jar;D:workRepositoryorgcodehausjacksonjackson-jaxrs1.8.3jackson-jaxrs-1.8.3.jar;D:workRepositoryorgcodehausjacksonjackson-xc1.8.3jackson-xc-1.8.3.jar;D:workRepositorytomcatjasper-compiler5.5.23jasper-compiler-5.5.23.jar;D:workRepositorycommons-elcommons-el1.0commons-el-1.0.jar;D:workRepositorynetjavadevjets3tjets3t0.9.0jets3t-0.9.0.jar;D:workRepositoryorgapachehttpcomponentshttpclient4.1.2httpclient-4.1.2.jar;D:workRepositoryorgapachehttpcomponentshttpcore4.1.2httpcore-4.1.2.jar;D:workRepositorycomjamesmurtyutilsjava-xmlbuilder0.4java-xmlbuilder-0.4.jar;D:workRepositorycommons-configurationcommons-configuration1.6commons-configuration-1.6.jar;D:workRepositorycommons-digestercommons-digester1.8commons-digester-1.8.jar;D:workRepositorycommons-beanutilscommons-beanutils-core1.8.0commons-beanutils-core-1.8.0.jar;D:workRepositoryorgapacheavroavro1.7.4avro-1.7.4.jar;D:workRepositorycomthoughtworksparanamerparanamer2.3paranamer-2.3.jar;D:workRepositoryorgxerialsnappysnappy-java1.0.4.1snappy-java-1.0.4.1.jar;D:workRepositorycomgooglecodegsongson2.2.4gson-2.2.4.jar;D:workRepositorycomjcraftjsch0.1.42jsch-0.1.42.jar;D:workRepositoryorgapachecuratorcurator-client2.6.0curator-client-2.6.0.jar;D:workRepositoryorgapachecuratorcurator-recipes2.6.0curator-recipes-2.6.0.jar;D:workRepositoryorgapachezookeeperzookeeper3.4.6zookeeper-3.4.6.jar;D:workRepositoryorgapachecommonscommons-compress1.4.1commons-compress-1.4.1.jar;D:workRepositoryorgtukaanixz1.0xz-1.0.jar;D:workRepositoryorgapachehadoophadoop-auth2.6.1hadoop-auth-2.6.1.jar;D:workRepositoryorgapachecuratorcurator-framework2.6.0curator-framework-2.6.0.jar;D:workRepositoryioconfluentkafka-avro-serializer1.0kafka-avro-serializer-1.0.jar;D:workRepositoryioconfluentkafka-schema-registry-client1.0kafka-schema-registry-client-1.0.jar;D:workRepositorycomfasterxmljacksoncorejackson-databind2.4.3jackson-databind-2.4.3.jar;D:workRepositorycomfasterxmljacksoncorejackson-annotations2.4.0jackson-annotations-2.4.0.jar;D:workRepositorycomfasterxmljacksoncorejackson-core2.4.3jackson-core-2.4.3.jar;D:workRepositoryorgmariuszgromadamathMathParser.org-mXparser4.2.0MathParser.org-mXparser-4.2.0.jar;D:workRepositorycommons-beanutilscommons-beanutils1.9.3commons-beanutils-1.9.3.jar;D:workRepositorycommons-loggingcommons-logging1.2commons-logging-1.2.jar;D:workRepositorycommons-collectionscommons-collections3.2.2commons-collections-3.2.2.jar;D:workRepositoryorgapachecommonscommons-collections44.3commons-collections4-4.3.jar;D:workRepositorycomgoogleguavaguava28.1-jreguava-28.1-jre.jar;D:workRepositorycomgoogleguavafailureaccess1.0.1failureaccess-1.0.1.jar;D:workRepositorycomgoogleguavalistenablefuture9999.0-empty-to-avoid-conflict-with-guavalistenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar;D:workRepositorycomgooglecodefindbugsjsr3053.0.2jsr305-3.0.2.jar;D:workRepositoryorgcheckerframeworkchecker-qual2.8.1checker-qual-2.8.1.jar;D:workRepositorycomgoogleerrorproneerror_prone_annotations2.3.2error_prone_annotations-2.3.2.jar;D:workRepositorycomgooglej2objcj2objc-annotations1.3j2objc-annotations-1.3.jar;D:workRepositoryorgcodehausmojoanimal-sniffer-annotations1.18animal-sniffer-annotations-1.18.jar;D:workRepositorycommons-codeccommons-codec1.13commons-codec-1.13.jar;D:workRepositoryjunitjunit4.12junit-4.12.jar;D:workRepositoryorghamcresthamcrest-core1.3hamcrest-core-1.3.jar;D:workRepositoryorgslf4jslf4j-api1.7.25slf4j-api-1.7.25.jar;D:workRepositoryorgapachelogginglog4jlog4j-core2.7log4j-core-2.7.jar;D:workRepositoryorgapachelogginglog4jlog4j-api2.7log4j-api-2.7.jar;D:workRepositoryorgapachelogginglog4jlog4j-slf4j-impl2.7log4j-slf4j-impl-2.7.jar;D:workRepositorycomalibabafastjson1.2.24fastjson-1.2.24.jar" com.demo.lock.LockExample Thread 1: Going to print a document Thread 9: Going to print a document Thread 8: Going to print a document Thread 5: Going to print a document Thread 4: Going to print a document Thread 6: Going to print a document Thread 7: Going to print a document Thread 3: Going to print a document Thread 2: Going to print a document Thread 0: Going to print a document Thread 1: PrintQueue: Printing a Job during 2 seconds :: Time - Tue May 26 12:48:07 CST 2020 Thread 1: The document has been printed Thread 9: PrintQueue: Printing a Job during 6 seconds :: Time - Tue May 26 12:48:09 CST 2020 Thread 9: The document has been printed Thread 8: PrintQueue: Printing a Job during 2 seconds :: Time - Tue May 26 12:48:15 CST 2020 Thread 8: The document has been printed Thread 5: PrintQueue: Printing a Job during 1 seconds :: Time - Tue May 26 12:48:18 CST 2020 Thread 5: The document has been printed Thread 4: PrintQueue: Printing a Job during 9 seconds :: Time - Tue May 26 12:48:20 CST 2020 Thread 4: The document has been printed Thread 6: PrintQueue: Printing a Job during 9 seconds :: Time - Tue May 26 12:48:29 CST 2020 Thread 6: The document has been printed Thread 7: PrintQueue: Printing a Job during 7 seconds :: Time - Tue May 26 12:48:39 CST 2020 Thread 7: The document has been printed Thread 3: PrintQueue: Printing a Job during 0 seconds :: Time - Tue May 26 12:48:47 CST 2020 Thread 3: The document has been printed Thread 2: PrintQueue: Printing a Job during 2 seconds :: Time - Tue May 26 12:48:47 CST 2020 Thread 2: The document has been printed Thread 0: PrintQueue: Printing a Job during 8 seconds :: Time - Tue May 26 12:48:50 CST 2020 Thread 0: The document has been printed Process finished with exit code 0
The main part of this example is in the printJob () method of the PrinterQueue class. When we want to use locks to implement critical parts and ensure that only one executing thread runs the code block, we must create a ReentrantLock object. At the beginning of the method, we must use the lock () method to control the lock.
At the end of the critical section, we must use the unlock () method to release control of the lock and allow other threads to run the critical section. If you do not call the unlock () method at the end of a critical section, other threads waiting for the block will always be waiting, causing a deadlock condition. If you use the try catch block in the key section, don't forget to put the sentence containing the unlock () method in the final section