Table of Contents
Comparison between Lock and synchronized
Home Java javaTutorial How to use Lock in Java multithreading

How to use Lock in Java multithreading

May 12, 2023 pm 02:46 PM
java lock

After Jdk1.5, under the java.util.concurrent.locks package, there is a set of interfaces and classes that implement thread synchronization. When it comes to thread synchronization, everyone may think of the synchronized keyword,

This It is a built-in keyword in Java, used to handle thread synchronization. However, this keyword has many flaws and is not very convenient and intuitive to use, so Lock appears. Below, we

will compare Explain Lock.

Usually we encounter the following problems when using the synchronized keyword:

(1) Uncontrollability, unable to lock and release locks at will.

(2) The efficiency is relatively low. For example, we are currently reading two files concurrently. The reading and reading have no influence on each other. However, if synchronized is used for the read object to achieve synchronization,

So as long as one thread enters, other threads will have to wait.

(3) There is no way to know whether the thread has acquired the lock.

Lock can solve the above synchronized problems very well, and after jdk1.5, various locks are also provided, such as read-write locks, but there is one thing to note, using synchronized

When it is critical, there is no need to manually release the lock, but when using Lock, you must manually release the lock. Let's learn about Lock locks.

Lock is an upper-layer interface. Its prototype is as follows, providing a total of 6 methods:

public interface Lock {
  // 用来获取锁,如果锁已经被其他线程获取,则一直等待,直到获取到锁
   void lock();
  // 该方法获取锁时,可以响应中断,比如现在有两个线程,一个已经获取到了锁,另一个线程调用这个方法正在等待锁,但是此刻又不想让这个线程一直在这死等,可以通过
    调用线程的Thread.interrupted()方法,来中断线程的等待过程
  void lockInterruptibly() throws InterruptedException;
  // tryLock方法会返回bool值,该方法会尝试着获取锁,如果获取到锁,就返回true,如果没有获取到锁,就返回false,但是该方法会立刻返回,而不会一直等待
   boolean tryLock();
  // 这个方法和上面的tryLock差不多是一样的,只是会尝试指定的时间,如果在指定的时间内拿到了锁,则会返回true,如果在指定的时间内没有拿到锁,则会返回false
   boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
  // 释放锁
   void unlock();
  // 实现线程通信,相当于wait和notify,后面会单独讲解
   Condition newCondition();
}
Copy after login

So how to use these methods? As we mentioned earlier, using Lock requires manual release of the lock. However, if an exception is thrown in the program, the lock cannot be released and may cause deadlock.

So when we use Lock , there is a fixed format, as follows:

Lock l = ...;
      l.lock();
      try {
        // access the resource protected by this lock
      } finally {// 必须使用try,最后在finally里面释放锁
        l.unlock();
      }
Copy after login

Let’s look at a simple example, the code is as follows:

/**
 * 描述:Lock使用
 */
public class LockDemo {
    // new一个锁对象,注意此处必须声明成类对象,保持只有一把锁,ReentrantLock是Lock的唯一实现类
   Lock lock = new ReentrantLock();
   public void readFile(String fileMessage){
      lock.lock();// 上锁
      try{
         System.out.println(Thread.currentThread().getName()+"得到了锁,正在读取文件……");
         for(int i=0; i<fileMessage.length(); i++){
            System.out.print(fileMessage.charAt(i));
         }
         System.out.println();
         System.out.println("文件读取完毕!");
      }finally{
         System.out.println(Thread.currentThread().getName()+"释放了锁!");
         lock.unlock();
      }
   }
   public void demo(final String fileMessage){
      // 创建若干个线程
      ExecutorService service = Executors.newCachedThreadPool();
      // 提交20个任务
      for(int i=0; i<20; i++){
         service.execute(new Runnable() {
            @Override
            public void run() {
               readFile(fileMessage);
               try {
                  Thread.sleep(20);
               } catch (InterruptedException e) {
                  e.printStackTrace();
               }
            }
         });
      }
    // 释放线程池中的线程
      service.shutdown();
   }
}
Copy after login

Comparison between Lock and synchronized

1 , Function

lock and synchronized are both tools used in Java to solve thread safety issues.

2. Source

sychronized is a keyword in Java.

lock is an interface provided in the JUC package. This interface has many implementation classes, including our most commonly used ReentrantLock (reentrant lock).

3. Lock strength

sychronized can control the lock strength in two ways:

Modify the sychronized keyword at the method level.
is decorated on the code block.
Differences in lock objects:

If the lock object is a static object or a class object, then this lock is a global lock.
The lock object is a normal instance object, and the scope of this lock depends on the life cycle of this instance.
The strength of the lock is determined by the two methods lock() and unlock(). The code between the two methods is guaranteed to be thread-safe. The scope of the lock depends on the life cycle of the lock instance.

4. Flexibility

Lock is more flexible than sychronized.

lock can decide independently when to lock and release the lock. Just call the lock() and unlock() methods of lock.

sychronized Because it is a keyword, it cannot implement the non-blocking competition lock method. After one thread acquires the lock, other locks can only wait for that thread to release before they have a chance to acquire the lock.

5. Fair lock and unfair lock

Fair lock: Multiple threads obtain locks in the order in which they apply for locks. The threads will directly enter the queue to queue up, forever. Only the first person in the queue can get the lock.

Advantages: All threads can obtain resources and will not starve to death.
Disadvantages: Low throughput, except for the first thread in the queue, other threads will be blocked, and the CPU overhead of waking up blocked threads is high.
Unfair lock: When multiple threads acquire the lock, they will directly try to acquire it. If they cannot acquire it, they will enter the waiting queue. If they can acquire it, they will acquire the lock directly.

Advantages: It can reduce the overhead of CPU waking up threads, the overall throughput efficiency will be higher, and the CPU does not have to wake up all threads, which will reduce the number of awakened threads.
Disadvantages: The thread in the middle of the queue may not be able to obtain the lock or cannot obtain the lock for a long time, and eventually starve to death.
lock provides two mechanisms: fair lock and unfair lock (default unfair lock).

sychronized is an unfair lock.

6. Whether to release the lock due to exception

The release of the synchronized lock is passive and will only be released when the execution of the sychronized synchronized code block ends or an exception occurs.

When an exception occurs in the lock lock, the occupied lock will not be actively released. It must be released manually with unlock(), so we usually put the synchronization code block into try-catch and write unlock in finally. () method to avoid deadlock.

7. Determine whether the lock can be obtained

synchronized cannot.

lock provides a non-blocking competition lock method trylock(), and the return value is of type Boolean. It indicates that it is used to try to acquire the lock: it returns true if the acquisition is successful; it returns false if the acquisition fails. This method will return immediately no matter what.

8. Scheduling method

synchronized uses the wait, notify, and notifyAll methods of the object object itself, while lock uses Condition for scheduling between threads.

9. Whether it can be interrupted

synchronized can only wait for the lock to be released and cannot respond to interrupts.

You can use interrupt() to interrupt while waiting for the lock.

10. Performance

If the competition is not fierce, the performance is about the same; when the competition is fierce, the performance of lock will be better.

Lock lock can also use readwritelock to separate reading and writing, improving the efficiency of multi-threaded reading operations.

11. Synchronized lock upgrade

The synchronized code block is implemented by a pair of monitorenter/monitorexit instructions. The implementation of Monitor completely relies on the mutex lock inside the operating system. Because it requires switching from user mode to kernel mode, synchronization operation is an undifferentiated heavyweight operation.

So now the JVM provides three different locks: biased locks, lightweight locks, and heavyweight locks.

Biased lock:
When no competition occurs, biased lock is used by default. The thread will use the CAS operation to set the thread ID on the object header to indicate that the object is biased towards the current thread.

Purpose: In many application scenarios, the life cycle of most objects will be locked by at most one thread. Using biased locks can reduce the overhead when there is no competition.

Lightweight lock:
The JVM compares the threadID of the current thread and the threadID in the Java object header to see if it is consistent. If it is inconsistent (for example, thread 2 wants to compete for the lock object), then you need to check the record in the Java object header. Whether thread 1 is alive (the biased lock will not be actively released, so it is still the stored threadID of thread 1). If it is not alive, then the lock object is still a biased lock (the threadID in the object header is thread 2's); if it survives, then revoke Bias lock, upgraded to lightweight lock.

When other threads want to access resources with lightweight locks, spin lock optimization will be used to access the resources.

Purpose: There are not many threads competing for the lock object, and the threads do not hold the lock for a long time. Because blocking the thread requires the CPU to transfer from user mode to kernel mode, which is expensive. If the lock is released shortly after blocking, the gain is not worth the loss. Therefore, it is better not to block the thread at this time and let it spin to wait for the lock to be released.

Heavyweight lock:
If the spin fails, there is a high probability that the self-selection will fail again, so it is directly upgraded to a heavyweight lock to block threads and reduce CPU consumption.

When the lock is upgraded to a heavyweight lock, threads that have not grabbed the lock will be blocked and enter the blocking queue.

The above is the detailed content of How to use Lock in Java multithreading. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Java Spring Interview Questions Java Spring Interview Questions Aug 30, 2024 pm 04:29 PM

In this article, we have kept the most asked Java Spring Interview Questions with their detailed answers. So that you can crack the interview.

Break or return from Java 8 stream forEach? Break or return from Java 8 stream forEach? Feb 07, 2025 pm 12:09 PM

Java 8 introduces the Stream API, providing a powerful and expressive way to process data collections. However, a common question when using Stream is: How to break or return from a forEach operation? Traditional loops allow for early interruption or return, but Stream's forEach method does not directly support this method. This article will explain the reasons and explore alternative methods for implementing premature termination in Stream processing systems. Further reading: Java Stream API improvements Understand Stream forEach The forEach method is a terminal operation that performs one operation on each element in the Stream. Its design intention is

TimeStamp to Date in Java TimeStamp to Date in Java Aug 30, 2024 pm 04:28 PM

Guide to TimeStamp to Date in Java. Here we also discuss the introduction and how to convert timestamp to date in java along with examples.

Java Program to Find the Volume of Capsule Java Program to Find the Volume of Capsule Feb 07, 2025 am 11:37 AM

Capsules are three-dimensional geometric figures, composed of a cylinder and a hemisphere at both ends. The volume of the capsule can be calculated by adding the volume of the cylinder and the volume of the hemisphere at both ends. This tutorial will discuss how to calculate the volume of a given capsule in Java using different methods. Capsule volume formula The formula for capsule volume is as follows: Capsule volume = Cylindrical volume Volume Two hemisphere volume in, r: The radius of the hemisphere. h: The height of the cylinder (excluding the hemisphere). Example 1 enter Radius = 5 units Height = 10 units Output Volume = 1570.8 cubic units explain Calculate volume using formula: Volume = π × r2 × h (4

PHP: A Key Language for Web Development PHP: A Key Language for Web Development Apr 13, 2025 am 12:08 AM

PHP is a scripting language widely used on the server side, especially suitable for web development. 1.PHP can embed HTML, process HTTP requests and responses, and supports a variety of databases. 2.PHP is used to generate dynamic web content, process form data, access databases, etc., with strong community support and open source resources. 3. PHP is an interpreted language, and the execution process includes lexical analysis, grammatical analysis, compilation and execution. 4.PHP can be combined with MySQL for advanced applications such as user registration systems. 5. When debugging PHP, you can use functions such as error_reporting() and var_dump(). 6. Optimize PHP code to use caching mechanisms, optimize database queries and use built-in functions. 7

PHP vs. Python: Understanding the Differences PHP vs. Python: Understanding the Differences Apr 11, 2025 am 12:15 AM

PHP and Python each have their own advantages, and the choice should be based on project requirements. 1.PHP is suitable for web development, with simple syntax and high execution efficiency. 2. Python is suitable for data science and machine learning, with concise syntax and rich libraries.

Create the Future: Java Programming for Absolute Beginners Create the Future: Java Programming for Absolute Beginners Oct 13, 2024 pm 01:32 PM

Java is a popular programming language that can be learned by both beginners and experienced developers. This tutorial starts with basic concepts and progresses through advanced topics. After installing the Java Development Kit, you can practice programming by creating a simple "Hello, World!" program. After you understand the code, use the command prompt to compile and run the program, and "Hello, World!" will be output on the console. Learning Java starts your programming journey, and as your mastery deepens, you can create more complex applications.

How to Run Your First Spring Boot Application in Spring Tool Suite? How to Run Your First Spring Boot Application in Spring Tool Suite? Feb 07, 2025 pm 12:11 PM

Spring Boot simplifies the creation of robust, scalable, and production-ready Java applications, revolutionizing Java development. Its "convention over configuration" approach, inherent to the Spring ecosystem, minimizes manual setup, allo

See all articles