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 (). E.g:
Public class 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 is to implement the runnable interface, this interface has only one function, Run (), this function must be A class implementation that implements this interface. E.g:
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} public void startthreads () {thread1.start (); thread2.start ();}}
The two creation methods are different, the first is because inheritance from THREAD, only its own 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 latter way. The reason why most people prefer it is also here.
-------------------------
Let's talk about the four uses of Synchronized:
1. When the method declares, after the range operator (public, etc.), return to the type declaration (Void et al.). At this time, the thread is a member lock, that is, only one thread can enter the method, other threads To call this method at this time, you can only queue wait, the current thread (just after the thread inside the synchronized method), other threads can enter. For example: public synchronized void synmethod () {// method body }
2. Use a code block, Synchronized followed by parentheses, parentheses is a variable, 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 be entered}} 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 (thread.currentthread (). getName ());}}} For 3, if the thread enters, get the current object lock, then other threads are here Any operation on all objects on the class cannot be performed. Object-level use locks are usually a relatively rough way. 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 be locked as follows:
Class FinegrainLock {
Mymemberclass X, Y; Object Xlock = New Object (), YLOCK = New Object ();
Public void foo () {synchronized (xlock) {// access x here}
// Do Something Here - But don't use shared resources
Synchronized (YLOCK) {// Access Y Here}}
Public void bar () {synchronized (this) {// Access Both x and y here} // do sometying here - but don't use shared resources}}
4. Synchronized is a class in parentheses, at this time, the thread is an object 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; // array of references to retain a ArrayWithLockOrder last = a2; // local copy. 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 } 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 static methods and static variables Synchronization of code blocks, we usually use 4 to lock. ----------------------------- Let's 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 enables the object lock; Wait (long) is to lock the object lock After the thread release lock time is long (millisecond), get the lock again, Wait () and Wait (0) equivalence; notify () is a thread that is awakening a waiting object lock, if the waiting thread is not only one, then wake up The thread is determined by JVM; NotifyAll is a thread that wakes all waiting object lock. Here I also reiterate, we should use the notifyAll () method, because wake-up all threads are easier to get the JVM to find the most suitable Wake-up threads. 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, "produter1"); 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 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 what's blowing on this semaphore} Public void Run () {while (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);}} } Producer production, consumer consumption, generally there is no conflict, but when the stock is 0, consumers should not consume, but when the stock is the upper limit (here 10), the producer can not be produced. Please study the top Procedure, you must have a lot more than before. The above code illustrates Synchronized and Wait, Notify no absolute relationship, in the synchronized declaration method, code block, you can completely don't need Wait, Notify, etc., however, if In the case of some kind of contention of a resource, you must put the thread in a wait or awake. The article finally finished, basically written all my learning, but also left a little regret, such as Synchronized is a deep explanation and discussion of the class. Moreover, due to the limited ability, some places will definitely have errors. I hope that what suggests and criticism, please post below, I will fix the article. Thank you!