Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Synchronized principle of Java and example Analysis of Callable Interface

2025-02-24 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

Most people do not understand the knowledge points of this article "Synchronized principle of Java and Callable interface example analysis", so the editor summarizes the following contents, detailed content, clear steps, and has a certain reference value. I hope you can get something after reading this article. Let's take a look at this "Synchronized principle of Java and Callable interface example analysis" article.

I. basic characteristics

1. At the beginning, it is an optimistic lock, and if the lock conflicts are frequent, it will be converted to a pessimistic lock.

two。 It starts with a lightweight lock implementation, which is converted to a heavyweight lock if the lock is held for a long time.

3. Spin locking strategy used in implementing lightweight locks with high probability

4. It's an unfair lock.

5. It's a reentrant lock.

6. Not a read-write lock.

Second, lock the working process

JVM divides synchronized locks into no lock, bias lock, lightweight lock and heavy lock state. It will be upgraded in turn according to the situation.

Bias lock

Suppose the male master is a lock and the female master is a thread. If there is only one thread to use the lock, the male and female can live happily ever after even if they don't get a license to get married (avoiding high-cost operation). However, the female match appeared and tried to compete for the male master. At this time, no matter how expensive the operation cost of obtaining a license to get married was, the female master was bound to complete this action and let the female match give up.

A biased lock is not really a lock, but a "lock-biased mark" in the object header to record which thread the lock belongs to. If no other thread competes for the lock later, then there is no need for other synchronization operations (avoiding the overhead of locking and unlocking). If there are other threads competing for the lock later (which thread the current lock belongs to has just been recorded in the lock object, it is easy to identify whether the current thread applying for the lock is the previously recorded thread), then cancel the original biased lock state. Enter the general lightweight lock state

Biased locking is essentially equivalent to "delayed locking". Can not lock, do not lock, try to avoid unnecessary locking overhead. But the mark that should be made still has to be done, otherwise it is impossible to tell when it really needs to be locked.

Biased locks do not actually lock, but simply record a token in the lock's object header (recording the thread to which the lock belongs). If no other thread participates in the competitive lock, the locking operation will not be actually performed, thus reducing the program overhead. Once other thread contention is really involved, cancel the biased lock state and enter the lightweight lock state.

Lightweight lock

As other threads enter the competition, the biased lock state is eliminated and enters the lightweight lock state (adaptive spin lock). The lightweight lock here is implemented through CAS.

Check and update a piece of memory through CAS (such as null = > the thread reference)

If the update is successful, the lock is considered successful.

If the update fails, the lock is considered occupied and continues to spin waiting (without giving up CPU).

Spin operation keeps CPU idling, which is a waste of CPU resources. Therefore, the spin here will not continue all the time, but will no longer spin when it reaches a certain time / number of retries. The so-called "self-adaptation"

Weight lock

If the competition becomes more intense and the spin cannot get the lock state quickly, it will expand into a heavyweight lock, where the heavyweight lock refers to the mutex provided by the kernel.

To perform the locking operation, enter the kernel state first.

Kernel state determines whether the current lock has been occupied

If the lock is not occupied, the lock is successfully added and switched back to user mode.

If the lock is occupied, the lock fails. At this point, the thread enters the waiting queue of the lock and hangs. Waiting to be awakened by the operating system.

After a series of vicissitudes, the lock was released by other threads, and the operating system remembered the suspended thread, so it woke up the thread and tried to reacquire the lock.

Third, other optimized operation locks are eliminated

The compiler + JVM determines whether the lock can be eliminated. If you can, just eliminate it.

Some applications use synchronized in their code, but not in a multithreaded environment. (for example, StringBuffer)

StringBuffer sb = new StringBuffer (); sb.append ("a"); sb.append ("b"); sb.append ("c"); sb.append ("d")

At this point, each call to append involves locking and unlocking. But if you only execute this code in a single thread, then these locking and unlocking operations are unnecessary and waste some resource overhead.

Lock coarsening

If multiple locking and unlocking occurs in a piece of logic, the compiler + JVM will coarsening the lock automatically.

Leaders, give work tasks to subordinates

Method 1:

Make a phone call, assign task 1, and hang up.

Make a phone call, assign Task 2, and hang up.

Make a phone call, assign task 3, hang up.

Method 2:

Call, tell me Task 1, Task 2, Task 3, hang up.

IV. Callable interface

What is Callable?

Callable is an interface. It is equivalent to encapsulating a "return value" of the thread. It is convenient for programmers to calculate the results with the help of multithreading.

Callable and Runnable, as opposed to each other, describe a task. Callable describes tasks with return values, while Runnable describes tasks without return values. Callable usually needs to be used with FutureTask. FutureTask is used to save the returned results of Callable. Because Callable is often executed in another thread, it is uncertain when the execution is finished. FutureTask can be responsible for the work waiting for the results.

Code example: create a thread to calculate 1 + 2 + 3 +... + 1000 without using the Callable version

Public class Text {static class Result {public int sum = 0; public Object locker = new Object ();} public static void main (String [] args) throws InterruptedException {Result result = new Result (); Thread t = new Thread () {@ Override public void run () {int sum = 0; for (int I = 0; I

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report