Java multi-thread entry

xiaoxiao2021-03-06  87

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.

Finally, one day, I think it is time to figure out this question, so I will find relevant content online, and I can't find it in my stage. It is not too simple, it is a strike, I don't know cloud.

Waste the force of Nine Bull, finally, it is almost clear, there are many misunderstandings, which I have thoughtful and truth is very different. I think of my time spent, I really feel a bit more, so write it out, one is to prevent itself In the future, I will forget, the other is to give a point that can be referred to as I like me.

Gossip less, transfer to the topic!

First create from the thread. There are two forms of the creation of threads:

One is inheriting from the Thread class .hetive class is a specific class, ie not an 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 () {file: // do thread's things}}

The other is to implement the 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 () {file: // do thread's things} public void startthreads () {thread1.start (); thread2.start ( );} The two creation methods look different, but if they are unclear, they may make your procedures a mess. The differences have the following points: 1. When you want to inherit a certain class, you can only use the latter way. 2. The first kind of inheritance from Thread, only the object is created, but in quantity, There are several threads to create several self-objects; the second type only creates a self-object, but creates a few Thread objects. And the major difference between the two methods is here, please consider: if you are in the first Create several self-objects and start (), you will find that Synchronized does not work, the code block or method that has been locked can also have several threads, and the same variable, actually can have several threads. At the same time, you can change it. (For example, the following code) This is because in this program, although you play a few threads, you have created several objects, and each thread corresponds to each object, each thread change And the objects of the occupied object are different, so there is a phenomenon of several threads entering a method. In fact, it is not a method, but the same method of different objects. So, this time you have to lock, you can only declare the method or variable as static. After adding Static, you will find that the thread can control the method, and it is impossible to have two threads to enter the same way. It is because it is not that every object has a method, but all objects have a method, this method is a static method. If you use the thread with the second method, you will not have the above situation, because at this time, you only created a self-object, so the properties and methods of your own objects are common for threads. Therefore, I suggest that it is best to use the thread using the latter method.

public class mainThread extends Thread {int i = 0; public static void main (String args []) {mainThread m1 = new mainThread (); mainThread m2 = new mainThread (); mainThread m3 = new mainThread (); mainThread m4 = new MAINTHREAD (); magethread m6 = new mainthread (); m1.start (); m2.start (); m3.start (); m4.start (); m5.Start (); M6.Start ();} public synchronized void t1 () {i = i; try {thread.sleep (500);} catch (exception e) {} file: // Each thread enters the respective T1 ( The method, print the respective I system.out.println (thread.currentthread (). GetName () " i);} public void run () {SYNCHRONIZED (THIS) {while (true) {t1 () The following we will talk about the four uses of Synchronized: 1. Method declaration, after the range operator (public, etc.), return to the type declaration (Void et al.). You can only have a thread at a time. Entering this method, other threads want to call this method at this time, can only queue wait, the current thread (that is, the other threads can enter after the method is executed, for example: public synchronized void synmethod ) {File: // 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. For example: public int synmethod (int A1) {synchronized A1) {file: // Only one thread can enter} } 3. Synchronized is an object in brackets, at this time, the thread is subject to the 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 (thread.currentthread (). getname ());}}}

For 3, if the thread is entered, the object lock is obtained, then other threads cannot be performed any operation on all objects of the class. The 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) {file: // access x here} file: // do something here - But don't use shared resources synchronized (ylock) {file: // access y here}} public void bar () {synchronized (this) {File: // Access Both x and y Here} File: // Do Something Here - But don't use shared resources}} 4. Synchronized Beckhand is class. 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; i value = arr1 [i] arr2 [i];}} 4. For 4, if the thread is entered, the thread is not performed in this class, including static variables and static methods, in fact, for a static method And the synchronization of the code block of the static variable, we usually use 4 to lock. The relationship between the above four: the lock is associated with the object, each object has a lock, in order to execute the synchronized statement, thread must be able to get synchronized The lock specified in the statement is locked, an object has only a lock, after being obtained by a thread, it will no longer have this lock, the thread will get the lock back to the object after executing the SYNCHRONIZED statement. In front of the method, The SYNCHRONIZED modifier can declare a method as a synchronization method. The synchronization method gets a lock before execution. If this is a class method, the obtained lock is the lock of the Class class object related to the class of the declaration method. If this is an instance method, this lock is the lock of the THIS object. Talk below talk about some common methods: Wait (), Wait (), 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 the lock is again, Wait () and Wait (0) equivalent Notify () is a thread that wakes up a waiting object lock. If the waiting thread is more than one, the wake-up thread is determined by the JVM; NotifyAll is a thread that wakes all the waiting object lock. Here I also reiterated, We should use the NotifyAll () method, because the wake-up thread is easier to get JVM to find the wake-up thread than awakening a thread. For the above method, you can use it in the current thread. ILLEGALMONITORSTATEEXCEPTION: CURRENT Thread Not Owner. I will talk about Synchronized and Wait (), Notify (), etc.: 1. SYN Chronized place does not have Wait, Notify 2. There is a place for Wait, Notify. This is because Wait and Notify are not a thread class, but every object has a method, and these two methods are The object lock is related to the locked place, there must be synchronized. Also, please note: If you want to put the Notify and Wait methods, you must call NOTIFY to call Wait, because if you call Wait, the thread is no longer Current Thread.

Such examples: / ** * Title: JDeveloper's Java Projdect * Description: N / A * Copyright: Copyright (c) 2001 * Company: SOHO http://www.chinajavaworld.com * @Author jdeveloper@21cn.com * @version 1.0 * / import java.lang.Runnable; import java.lang.Thread; public class DemoThread implements Runnable {public DemoThread () {TestThread testthread1 = new TestThread (this, "1"); TestThread testthread2 = new TestThread (this, " 2 "); testthread2.start (); testthread1.start ();} public static void main (String [] args) {DemoThread demoThread1 = new DemoThread ();} public void run () {TestThread t = (TestThread) Thread .currentthread (); try {if (! t.getname (). EqualsignoreCase ("1")) {synchronized (this) {Wait ();}} while (true) {system.out.println ("@ Time IN Thread " T.GetName () " = " T.Increasetime ()); if (t.gettime ()% 10 == 0) {synchronized (this) {system.out.println (" **** ************************************** "); notify (); if (t.gettime () == 100) Break; Wait ();}}} catch (EXCEPTION E) {E.PrintStackTrace ();}}} Class Testthread Extends thread} Class Testthread Extends thread {private int Time = 0; Public Testthread (Runnable R, String Name) {Super (R, Name);} public int gettime () {return Time;} public int increasetime () {Return Time;}} The following we use the producer / consumer example to 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, "produter2"); 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 import; public semaphore (int N) {this.count = n;} public synchronized void Acquire () {while (count == 0) {Try {wait ();} catch (interruptedException e) {file: // keyp Trying}} count -;} public synchronized void release () {while (count == 10) {Try {Wait ();} catch (interruptedException e) {file: // Keep trying}} count ; notifyAll (); file: // 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 ("producer")) {release ();} system. Out.println (thread.currentthread (). getname () " count);}}} producers production, consumer consumption, generally have no conflict, but when stock is 0, consumers should not consumption. However, when the stock is the upper limit (here 10), the producer can not be produced. Please study the above procedure, you will definitely make a lot more than before. The above code shows Synchronized and Wait, Notify has no absolute relationship, in Synchronized The declaration method, the code block, you can completely do not need Wait, Notify, etc. It's all written, basically written all of my study, but I will leave some regrets, such as Synchronized is an in-depth description and discussion of the class. Moreover, due to the limited ability, some places will definitely have errors, hope I have seen what suggestions and criticism, please post below, I will fix the article. Thank you!

Author: qlampskyface contact the author: djb_skyface@tom.com

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

New Post(0)