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

What is the publishing object in java high concurrency?

2025-02-25 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

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

This article introduces what is the release object in java high concurrency, the content is very detailed, interested friends can refer to, hope to be helpful to you.

Publish object

Publish object: means that an object can be used by code outside the current scope.

Object escape: an erroneous release. When an object is not yet constructed, it is made visible to other threads.

We often need to publish objects such as returning references to objects through non-private methods of the class, or publishing objects through common static variables.

Simple example:

@ Slf4j@NotThreadSafepublic class UnsafePublish {private String [] states = {"a", "b", "c"}; public String [] getStates () {return states;} public static void main (String [] args) {UnsafePublish unsafePublish = new UnsafePublish (); log.info ("{}", Arrays.toString (unsafePublish.getStates (); unsafePublish.getStates () [0] = "d" Log.info ("{}", Arrays.toString (unsafePublish.getStates ());}}

Output:

15 main 42 INFO com.vincent.example.publish.UnsafePublish-[a, b, c] 15 main 42 INFO com.vincent.example.publish.UnsafePublish-[d, b, c]

Why do you want to make this example? UnsafePublish publishes a property through the getState () method, which can be accessed by any external thread of the class, so it is not safe to publish the object because we are not sure whether other threads will modify the property, so when other threads access the property, its value is uncertain, so the published object is thread-unsafe.

Object escape

Let's first look at an example:

@ Slf4j@NotThreadSafe@NotRecommendpublic class Escape {private int thisCannBeEscape = 0; public Escape () {new InnerClass ();} private class InnerClass {public InnerClass () {log.info ("{}", Escape.this.thisCannBeEscape);}} public static void main (String [] args) {new Escape ();}}

In this example, an inner class InnerClass is defined, which references a reference to the external class, which may be published before the object is constructed correctly, and there may be unsafe factors in it.

Secure publishing object

Initialize an object reference in a static initialization function

Save a reference to an object to a volatile type field or an AtomicReference object

Save a reference to an object to the final type field of a properly constructed object

Save a reference to an object to a domain protected by a lock

* / public class SingletonExample1 {/ / Private constructor private SingletonExample1 () {} / / Singleton object private static SingletonExample1 instance = null; / / static factory method public static SingletonExample1 getInstance () {if (instance = = null) {instance = new SingletonExample1 ();} return instance }}

The above code has no problem in the case of single thread, but there will be a problem in the case of multi-thread. The problem occurs in the code if (instance = = null) {instance = new SingletonExample1 ();} return instance;. Two threads can access this code at the same time, so it is possible that the code will be called twice, so that the two threads may get different instances. It is not thread safe to write in this way.

Lazy mode-thread safety @ ThreadSafe@NotRecommendpublic class SingletonExample3 {/ / Private constructor private SingletonExample3 () {} / / Singleton object private static SingletonExample3 instance = null; / / static factory method public static synchronized SingletonExample3 getInstance () {if (instance = = null) {instance = new SingletonExample3 ();} return instance;}}

This lazy mode is thread-safe, but it brings performance overhead. And this is an expense that we don't want. Therefore, this method of writing is not recommended.

Lazy mode-double synchronous lock singleton mode / * slob mode-> double synchronous lock singleton mode * instances of singletons are created on first use * / @ NotThreadSafe@ThreadSafe@NotRecommendpublic class SingletonExample4 {/ / private constructor private SingletonExample4 () {} / / Singleton object private static SingletonExample4 instance = null / / normal execution step / / 1.memory = allcate () allocates the memory space of the object / / 2.ctorInstance () initialization object / / 3.instance = memory setting instance points to the newly allocated memory / / JVM and CPU optimization Instruction rearrangement occurred / / 1.memory = allcate () memory space of allocation object / / 3.instance = memory setting instance points to newly allocated memory / / 2.ctorInstance () initialization object / / static factory method public static SingletonExample4 getInstance () {if (instance = = null) {/ / dual detection mechanism synchronized (SingletonExample4.class) {/ / synchronization Lock if (instance = = null) {instance = new SingletonExample4 () } return instance }} normal execution step 1.memory = allcate () allocate the memory space of the object 2.ctorInstance () initialize the object 3.instance = memory set instance to the newly allocated memory the steps above have no problem in the case of a single thread In the case of multithreaded JVM and CPU optimization, instruction rearrangement occurs: 1.memory = allcate () memory space of allocation object 3.instance = memory setting instance points to the newly allocated memory 2.ctorInstance () initialization object

Instruction rearrangement results in thread unsafety of double detection mechanism. Therefore, it is possible to restrict instruction rearrangement in CPU. You can use the volatile keyword to restrict instruction rearrangement.

Private static volatile SingletonExample5 instance = null

This makes it possible to achieve thread safety.

So there are two usage scenarios for the volatile keyword. 1. The amount of status indication. two。 Double test. Here is an application of dual detection.

* / @ ThreadSafepublic class SingletonExample2 {/ / Private constructor private SingletonExample2 () {} / / Singleton object private static SingletonExample2 instance = new SingletonExample2 (); / / static factory method public static SingletonExample2 getInstance () {return instance;}}

If there is no too much operation in the constructor of the singleton class, the hungry mode is acceptable. What are the shortcomings of the hungry model? If there is too much processing in the constructor, it will cause the class to load very slowly, so there may be performance problems. If you use hungry mode, only loading the class without actual calls will result in a waste of resources. Therefore, when using the hungry model, we must consider two problems, 1. There is not much processing in the private constructor. two。 This class will definitely be used and will not lead to a waste of resources. The hungry mode is thread-safe.

2@ThreadSafepublic class SingletonExample6 {/ / Private constructor private SingletonExample6 () {} static {instance = new SingletonExample6 ();} / singleton private static SingletonExample6 instance = null; / / static factory method public static SingletonExample6 getInstance () {return instance;} public static void main (String [] args) {System.out.println (getInstance ()) System.out.println (getInstance ());}}

At this time, the printed value is null

You need to write the private static SingletonExample6 instance = null; code before the static statement block:

/ * * hungry mode * singleton instance is created during class loading * / @ ThreadSafepublic class SingletonExample6 {/ / Private constructor private SingletonExample6 () {} / / Singleton object private static SingletonExample6 instance = null; static {instance = new SingletonExample6 ();} / / static factory method public static SingletonExample6 getInstance () {return instance } public static void main (String [] args) {System.out.println (getInstance ()); System.out.println (getInstance ());}}

We should pay attention to the order when writing static attributes and static blocks of code.

The enumerated pattern / * * hungry mode * singleton instance is created when the class is loaded * / @ ThreadSafe@Recommendpublic class SingletonExample7 {/ / private constructor private SingletonExample7 () {} public static SingletonExample7 getInstance () {return Singleton.INSTANCE.getInstance ();} private enum Singleton {INSTANCE; private SingletonExample7 singleton / / JVM guarantees that this constructor will only call Singleton () {singleton = new SingletonExample7 ();} public SingletonExample7 getInstance () {return singleton;}} absolutely once.

Compared with the lazy mode, the enumerated mode is easier to guarantee in terms of security, and secondly, compared with the hungry mode, it can only be initialized when it is actually called, and the value can be taken for subsequent use. It will not cause a waste of resources.

About java high concurrency in what is the release object is shared here, I hope the above content can be of some help to you, can learn more knowledge. If you think the article is good, you can share it for more people to see.

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

Internet Technology

Wechat

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

12
Report