Puzzles encountered when learning multithreading

xiaoxiao2021-03-06  86

It has been a lot of time in contact with the multi-thread, but also a lot of things, but always feel that it is not so moving, when Debug, it will be more worried about what problems in synchronization, think of "Programmer" Written code "This sentence, I feel that it is not fake. I finally had one day, I think it is time to figure out this question, so I will find relevant content on the Internet, and I can't find this stage. It should be seen, it is not too simple, it is a strike, I don't know what the cloud. I finally almost figured out, there were many misunderstandings. I used to be very different from the truth. I think of my time spent. I really feel a bit more, so write it out, one is to prevent yours, I will forget it later, II is to give a point like I understand that I can refer to the stuff. Gossip less, transfer to the topic! - ------------------------------- First from the thread. There are two forms of thread creation: - ------------------------------- One is inheriting from the Thread class. THREAD class is a concrete class, ie Abstract class, which encapsulates the behavior of threads. To create a thread, the programmer must create a new class exported from the Thread class. The programmer completes useful work by overlying the run () function of Thread. The user does not call this function directly; but by calling the Start () function of Thread (), the function calls Run (). For example: public class test () {public test () {} public static void main (String args []) {test t1 = new test (); test t2 = new test (); t1.start (); t2.start (); public void Run () {// do thread's things}} --------------------------- the other Runnable interface, this interface has only one function, Run (), this function must be implemented by a class that implements this interface.

For example: public class Test implements Runnable {Thread thread1; Thread thread2; public Test () {thread1 = new Thread (this, "1"); thread2 = new Thread (this, "2");} public static void main (String Args []) {test t = new test (); t.startthreads ();} public void run () {// do thread's things} (); thread1.start (); thread2.start (); }} The difference between the two creation methods is not large. The first kind of inherits from Thread, only the object is created, the second kind has to create the Thread object. But when you want to inherit a certain class, you can only use the last one. Most people prefer the reason for the reason is also this. ------------------------- Let's talk about SYNCHRONIZED 4 Type of use: 1. Method declaration, use, place it before the range operator (public, etc.), return to the type declaration (Void et al.). At this time, thread is a member lock, that is, only one thread can enter Method, other threads want to call this method at this time, can only queue wait, current thread (that is, the other threads can enter after the method is executed, for example: public synchronized void synmethod () { // Method} 2. Use a code block, Synchronized followed by parentheses, parentheses is variables so that only one thread enters the code block at a time. At this time, the thread is a member lock. For example: public int synmethod INT A1) {Synchronized (A1) {// One thread can only have a thread into}} 3. Synchronized is an object. At this time, the thread is an object lock. For example: public class mythread implements runnable {public static Void main (string args []) {mythread mt = new mythread (); thread t1 = new thread (MT, "T1"); thread t2 = new thread (MT, "T2"); Thread T3 = New Thread (MT, "T3"); Thread T4 = New Thread (MT, "T4"); Thread T5 = New Thread (MT, "T5"); Thread T6 = New Thread MT, "T6"); t1.start (); t2.start (); t3.start (); t4.start (); t5.Start (); t6.start ();} public void Run () { Synchronized (this) {system.out.println (threeRead.currentthread (). getName ());}}} For 3, if the thread enters, get the current object lock, then other threads on all objects on this class Operation cannot be done. Object-level use lock is usually a relatively rough method. Why do you want to lock the entire object without allowing other threads to use other synchronization methods in the object to access shared resources? If an object has multiple resources, it is not necessary to lock all threads outside only to let a thread use some of the resources.

Since each object is locked, you can use the virtual object to lock: Class Finegraholdlock {MymemberClass X, Y; Object Xlock = New Object (), YLOCK = New Object (); public void foo () {synchronized ( XLOCK) {// Access X Here} // do sometying here - But don't use shared resourceynchronized (ylock) {// access y here}} public void bar ()}}}}} {Synchronized (this) {// Access Both x and Y Here} // Do Something Here - But Don't Use Shared Resources}} 4. Synchronized is class, at this time, the thread is a target lock. For example: Class ArraywithlockOrder {private static long Num_locks = 0; private Long lock_order; private int [] arr; public arraywithlockorder (int [] a) {arr = a; synchronized (arraywithlockorder.class) {// ----- Here Num_locks ; // Lock number plus 1. Lock_order = num_locks; / / Set the unique Lock_Order for this object instance. }} Public long lockOrder () {return lock_order;} public int [] array () {return arr;}} class SomeClass implements Runnable {public int sumArrays (ArrayWithLockOrder a1, ArrayWithLockOrder a2) {int value = 0; ArrayWithLockOrder first = a1 // Reserved an arraywithlockorder last = A2; / / local copy of the array reference. INT size = a1.Array (). Length; if (size == a2.Array (). Length) {if (a1.lockorder ()> A2.lockorder ()) / / Determine and set the lock {//// order. First = a2; LAST = a1;} synchronized (first) {// locked the object in the correct order. Synchronized (last) {int [] arr1 = a1.Array (); int [] arr2 = a2.Array (); for (int i = 0; ivalue = arr1 [i] arr2 [i];

}

}

}

Return Value;

}

Public void run () {

// ...

}

}

For 4, if the thread enters, the thread is not performed in this class, including static variables and static methods, in fact, for synchronization of code blocks containing static methods and static variables, we usually use 4 to lock.

-----------------------------

Let's talk about some common methods:

Wait (), WAIT (LONG), NOTIFY (), NotifyAll (), etc. is the instance method of the current class.

Wait () is a thread release lock that holds an object lock;

WAIT (long) is a thread release lock time that holds an object lock is long (milliseconds), and then get the lock again, Wait () and Wait (0) equivalent;

Notify () is a thread that wakes up a waiting object lock. If the waiting thread is not only one, the waken thread is determined by the JVM;

NotifyAll is a thread that wakes up all waiting object locks. Here I also reiterate us, we should use the NotifyAll () method, because wake up all threads easier to get JVM to find the wake-up thread.

For the above method, only in the current thread can be used, otherwise the runtime error java.lang.illegalMonitorstateException: Current Thread Not Owner.

----------------------------

Below, I am talking about the relationship between SYNCHRONIZED and WAIT (), Notify ():

In fact, the use of producers / consumers will best explain the relationship between them:

Public class test {

Public static void main (string args []) {

Semaphore S = New Semaphore (1);

Thread T1 = New Thread (s, "producer1");

Thread T2 = New Thread (s, "producer2");

Thread T3 = New Thread (s, "producer3");

Thread T4 = New Thread (s, "consumer1");

Thread T5 = New Thread (s, "consumer2");

Thread T6 = New Thread (s, "consumer3");

T1.Start ();

T2.Start ();

T3.Start ();

T4.Start ();

T5.Start ();

T6.Start ();

}

}

Class Semaphore

Implements runnable {

PRIVATE INT COUNT;

Public semaphore (int N) {

THIS.COUNT = N;

}

Public synchronized void acquire () {

WHILE (count == 0) {

Try {

Wait ();

}

Catch (InterruptedException E) {

// Keep Trying

}

}

count -;

}

Public synchronized void release () {

WHILE (count == 10) {

Try {

Wait ();

}

Catch (InterruptedException E) {

// Keep Trying

}

}

COUNT ;

Notifyall (); // alert a thread this's blocking on this semaphore

}

Public void run () {

While (true) {

IF (thread.currentthread (). getName (). Substring (0,8). Equalsignorecase ("consumer")) {

Acquire ();

}

Else if (thread.currentthread (). GetName (). Substring (0,8) .Equalsignorecase ("Producter")) {

Release ();

}

System.out.println (thread.currentthread (). Getname () " count);

}

}

}

Production, consumer consumption, generally there is no conflict, but when inventory is 0, consumers should not consumption, but when stocks are the upper limit (here 10), the producer can not be produced. Please study the above Procedure, you will have a lot more than before.

The above code illustrates Synchronized and Wait, Notify has no absolute relationship, in the method of synchronized declaration, code block, you can do it without Wait, Notify, etc., however, if threads have some kind of contention In the case, you must put the thread in a wait or wake. The article is finally written. Basically, I have written all my learning income, but I will leave some regrets, such as Synchronized is a deep instructions and discussion. Moreover, the article is limited by its own ability, some places will definitely have errors, I hope to have any suggestions and criticism, please post below, I will fix the article. Thank you!

转载请注明原文地址:https://www.9cbs.com/read-106202.html

New Post(0)