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 are the knowledge points of threads in Java

2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

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

This article introduces the relevant knowledge of "what are the knowledge points of threads in Java". In the operation of actual cases, many people will encounter such a dilemma, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!

1. Resource conflict, if two threads are indeed modifying the same object, the conflict of shared resources will be even worse, because it is possible to set the object to an incorrect state. Through the introduction of the simple concept of "semaphore", it is regarded as a flag object for communication between two threads. If the value of the semaphore is zero, the resource it monitors is available, but if the value is non-zero, the monitored resource is not available, so the thread must wait. When the resource is available, the thread increases the value of the semaphore and then continues to execute the monitored resource. The operation of increasing and decreasing semaphores is defined as an atomic operation, which ensures that two threads will not conflict when accessing the same resource at the same time.

Define a simplified semaphore:

Public class Semaphore implements Invariant {private volatile int semaphore= 0; public boolean available () {return semaphore==0;} public void acquire () {+ + semaphore;} public void release () {--semaphore;} public InvariantSate invariant () {int val= semaphore; if (val==0 | | val==1) return new InvariantOk (); else return new InvariantFailure (new Integer (val));} 12345678910111213

(the Invariant interface is given in the blog: thread testing framework.) set the semaphore field to volatile to ensure that the compiler does not optimize any operations that read this value.

two。 To solve the competition for shared resources, as mentioned earlier, thread scheduling mechanisms can be advised through yield () and setPriority (), but these suggestions may not be very effective, depending on your specific platform and JVM implementation. Java provides built-in support to prevent resource conflicts in the form of the keyword synchronized. Shared resources are generally judged by memory in the form of objects, but they can also be files, input / output ports, or printers. To control access to a shared resource, you must first wrap it into an object. Then mark all the methods that want to access the resource as synchronized. That is, once a thread is in a method marked synchronized, all other threads that want to call any synchronized method in the class will be blocked before the thread returns from that method.

Each object contains a single lock (also known as a monitor), which itself is part of the object (without writing any special code). When any of its synchronized methods are called on an object, the object is locked, and other synchronized methods on the object can only be called after the previous method has been called and released.

There is also a lock for each class (as part of the class's Class object), so the synchronized static method can prevent concurrent access to static data within the scope of the class.

3. An atomic operation, that is, an operation that cannot be interrupted by a thread scheduling mechanism; once the operation starts, it must be executed before the possible "context switch" (switch to another thread). If the variable type in question is a basic type other than long or double, a simple assignment or return operation on the variable is considered an atomic operation. However, as long as you add volatile to long or double, the operation is atomic. Note that the self-increment operation in JVM is not an atomic operation, it involves a read and a write, so even in such a simple operation, there is room for problems for the thread. When a thread is working, each thread may have a local stack to maintain copies of some variables. if a variable is defined as volatile, it is tantamount to telling the compiler not to do any optimization, but to operate the variable directly in main memory.

4. The safe way to ensure that the above problems are resolved is to use the following methods:

1) if you want to synchronize a method in a class, * synchronize all methods. If you ignore one of them, it is often difficult to determine whether this will have a negative impact.

2) be very careful when removing the synchronization control of the method. This is usually done based on performance considerations, but in JDK1.3 and JDK1.4, the burden of synchronization control has been greatly reduced. In addition, this should only be done when using performance evaluation tools to confirm that synchronization control is indeed a performance bottleneck.

5. If you just want to prevent multiple threads from accessing part of the code inside the method at the same time instead of preventing the whole method, you can use the synchronized keyword to separate the code snippet, which is called a "critical area," in which case synchronized is used to specify an object whose lock is used to synchronize the code in curly braces:

Synchronized (syncObject) {/ / This code can be accessed / / by only one thread at a time} 1234

The time performance of multiple threads accessing objects can be significantly improved by using synchronization control blocks instead of synchronizing the entire method. Note that when methods in an object are synchronized on different locks, two threads can access the same object:

Class DualSynch {private Object syncObject = new Object (); public synchronized void f () {System.out.println ("Inside f ()"); try {Thread.sleep (500);} catch (InterruptedException e) {throw new RuntimeException (e);} System.out.println ("leaving f ()") } public void g () {synchronized (syncObject) {System.out.println ("Inside g ()"); try {Thread.sleep (500);} catch (InterruptedException e) {throw new RuntimeException (e);} System.out.println ("leaving g ()") } public class SyncObject {public static void main (String [] args) {final DualSynch ds = new DualSynch (); new Thread () {public void run () {ds.f ();}} .start ();; ds.g ();}} 123456789101112131415171819202232426272829303133343536373839404142

The f () method of the DualSync object is synchronized on this (through synchronization on the entire method), and the synchronization control block of g () is synchronized on the syncObject object, so the two synchronization controls are independent of each other, and the two methods are fishy at the same time, so they do not block on the synchronization control of the object. Therefore, the code snippet that accesses the shared resource must be wrapped into an appropriate synchronization control block.

6. A thread has four states: new, ready, dead, and blocked (the program can run, but there is a condition that prevents it from running). Reasons for entering the blocking state:

1) put the thread into hibernation by calling sleep (miliseconds) and do not run for a specified period of time.

2) call wait () to suspend the thread until it gets a notify () or notifyAll () message before it enters the ready state.

3) the thread is waiting for some input / output to complete.

4) the thread calls its synchronization method on an object, but the object lock is not available.

7. In order to avoid conflicts between threads, the "handshake mechanism" is used, which can be safely implemented by Object's methods wait () and notify (). Note that the lock is not released when sleep () is called, and the call to the wait () method does release the lock, which means that other synchronization control methods in the thread object can be called during the call to wait (). When a thread encounters a call to wait () in the method, the thread's execution is suspended and the lock on the object is released.

There are two forms of wait (), one that accepts milliseconds like sleep (), with the difference:

1) the object lock is released during wait ().

2) you can reply execution from wait () via notify (), notifyAll (), or instruction time expiration.

The other is without parameters, and wait () waits until it receives a message from notify () or notifyAll ().

The methods 8.wait (), notify (), and notifyAll () are part of the base class Object, not part of Thread like sleep (). Because the locks used for these functions are also part of all objects, you can put the wait () method in any synchronous control method, regardless of whether the class inherits Thread or implements the Runnable interface. Threads that can only call wait (), notify (), or notifyAll () in synchronization control methods or synchronization control blocks must "hold" (acquire) the lock of the object before calling these methods. Sleep does not need to manipulate locks, so it can be called in asynchronous control methods.

Synchronized (x) {x.notify ();} "what are the knowledge points of threads in Java"? thank you for reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!

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