Java Thread

xiaoxiao2021-03-06  17

A Thread Is A Single Sequential Flow Of Control Withnin a program (thread is a separate control flow in a process). A process can have several threads. Java supports multi-threads through the Java.lang.Thread class. The data and methods of the thread execution are encapsulated in the Thread class, and combine the multithreading and object-oriented structures.

Java provides two ways to create threads, one is to inherit the Thread class and override the RUN method, and the other is to implement the interface runnable.

Inherit Thread class

Import java.lang.thread;

Import java.lang.math;

Import java.lang.InterruptedException;

Public class simplethread extends thread {

// Constructor, set the name of the thread. Otherwise, the automatically generated name format is "Thread -" n, n is an integer.

Public SimpleThread (String Str) {

Super (STR);

}

Public void run () {

For (int i = 0; i <10; i ) {

System.out.println (i " GetName ());

Try {

// Sleep

Sleep ((long) (Math.random () * 1000);

} catch (interruptedexception e) {}

}

System.out.println ("DONE!" GetName ());

}

}

// thread's START method

Public native synchronized void start ()

Enable the thread to begin; Java virtual machine calls the thread RUN method.

The result is two threads run simultaneously: the current thread (the thread returned by the method) and the other thread (thread of the method RUN).

// thread's RUN method

Public void Run ()

If the thread is constructed with a different runnable run object, the RUN method of the Runnable object is called; otherwise, the method will return to do anything.

The subclass of Thread must override this method.

Throw: ILLEGALTHREADSTATEEXCEPTION If the thread is already started.

Although the Run () function implements parallel processing of multiple threads, the Run () function cannot be called directly, but the Run () function is called by calling the start () function. When you call START (), the start () function will first perform the initialization of multi-threaded (this is why the RUN () function cannot be called directly), and then call the Run () function.

Public class twothreadsdemo {

Public static void main (String [] args) {

New SimpleThread ("jamaica"). start ();

New SimpleThread ("Fiji"). start ();

}

}

Implement the interface runnable

If there is a class, it has inherited a class and wants to implement multithreading, so you can implement the runnable interface.

1) The runnable interface has only one Run () function.

2) Generate a Thread object with an object that implements the Runnable interface as a parameter, and then call the Start () function of the Thread object to perform parallel operations. If a THREAD object is generated as a parameter, when calling the start () function, start () is called the Run () function in the implementation class of the runnable interface when calling the start () function. Import java.lang.thread;

Import java.lang.system;

Import java.lang.math;

Import java.lang.InterruptedException;

Import java.lang.Runnable;

Class Mythread Implements Runnable {

String name;

Private thread mythread = null;

Public mythread (String name) {

THIS.NAME = Name;

}

Public void start () {

IF (mythread == null) {

Mythread = New Thread (this, "clock");

mythread.start ();

}

}

Public void run () {

Thread Curthread = thread.currentthread ();

IF (curthread == mythread) {

For (int i = 0; i <10; i ) {

System.out.println (i " GetName ());

Try {

// Sleep

// There is no method in the interface runnable SLEEP ()

Thread.sleep (1000);

} catch (interruptedexception e) {}

}

System.out.println ("DONE!" GetName ());

}

}

}

to sum up:

Two ways to provide thread RUN methods:

1. Inherit the java.lang.Thread class and rewrite the RUN method

2. Implement the java.lang.Runnable interface and implement the RUN method

If the class is inherited from other classes, it should be used to implement a java.lang.Runnable interface.

Some common methods

■ CURRENTTHREAD () This is a class method that returns the thread currently executing.

■ Isalive () discriminates if a thread is still alive, including this thread is being executed or has an opportunity to be executed. Returns a Boolean value.

■ Suspend () hangs a thread and makes this thread can only be activated by the resume () method.

■ Resume () uses Suspend (). Wake up thread.

■ Yeild () forced threads to deliver the right to use other threads.

■ STOP () makes the thread into the dead state.

Thread lifecycle

● New Thread (New Thread)

After creating a thread object with a New method, it is just an empty thread object, and no system resources are allocated. When the thread is in this state, you can only start or terminate any other operations that will trigger an unlegalthreadStateException.

● Runnable Start () method generates the resource, scheduling thread execution, and call the thread Run () method. At this time, the thread is running state. This state is not called a running state because the thread at this time is not always occupied. Especially for the PC with only one processor, there is only one thread occupancy process in which the running state. Java achieves sharing of multi-threads to process machines by scheduling. ● NOT Runnable

When any of the situations below occurs, the thread enters uncomfortable state.

A Thread Becomes NOT Runnable When Of these Events Occurs:

1) IF A Thread Has Been Put to Sleep, The Specified Number of MilliseConds Must Elapse. () Method is called)

2) Suspend () method is called;

3) The Thread Calls The Wait Method to Wait for a Specific Condition To Be Satisifed. (Thread uses Wait () to wait for condition variables)

4) The Thread is blocking on I / O. (Thread is waiting for I / O)

When the third case occurs, the thread is waiting state (waiting for a certain event that can return to the running state) even if the processor is idle, the thread cannot operate. When the thread returns the condition of the running state, the thread is running, once the processor is available, the thread will run again. (For example, the process hangs in the method suspend () will wait for the method Resume () to be awakened)

For each entrance into the Not Runnable state, there is a specific and distinct escape route that returns the thread to the Runnable state. An escape route works only for its corresponding entrance. For example, if a thread has been put to sleep, then the Specified Number of Milliseconds Must Elapse Before The Thread Becomes Runnable Again. The Following List Describes The Escape Route for Every Entrance Into the Not Runnable State:

(For each entrance to the non-operating state, there is a special and clear circuit returns to the running state of the thread. This loop is tightly working. For example, a thread SLEEP must return after a period of time. Running status. The following list describes the loop corresponding to the non-operating state entry)

If A Thread Has Been Put To Sleep, The Specified Number of MilliseConds Must Elapse. (If threaded Sleep, you must wait for the set time)

If a thread is waiting for a condition, then another object must notify the waiting thread of a change in condition by calling notify or notifyAll. More information is available in Synchronizing Threads. (If the thread is waiting for the condition, then the other object must by changing the conditions To notify the waiting thread)

If a thread is blocked on i / o, the I / O Must Complete. (If the thread is waiting, the I / O operation must be completed) ● Death state (DEAD)

When the Run () method returns, or other thread calls the stop () method, the thread enters the death state. Usually applet uses its STOP () method to terminate all threads it generate.

The isalive method

If the thread has run and does not stop, the isalive method returns true. If the IsAlive method returns false, it indicates that the thread may be a new thread or enter the death state. If the isalive method returns true, the thread can be operable or unable to run. Therefore, it is not possible to distinguish between new threads and death status through Isalive, can only distinguish between running threads and uncomfortable threads.

Synchronization of thread

Producer / consumer model

If a thread is another providing service, then we refer to the thread of the serving service as the producer, and another thread is called a consumer.

Assuming that the producer produces an integer of 0-9 and stores in a public object CubbyHole, consumers get an integer generated by the producer from the CubbyHole object. Assuming that the producer thread will be a random time of SLEEP.

Class cubbyhole {

PRIVATE INT CONTENTS;

Public int GET () {

Return Contents;

}

Public void Put (int CONTENTS) {

THIS.COUTENTS = Contents;

}

}

// producer

Class producer extends thread {

PRIVATE CUBBYHOLE HOLE;

Public product (cubbyhole hole) {

THIS.HOLE = Hole;

}

Public void run () {

For (int i = 0; i <10; i ) {

Hole.Put (i);

Try {

Math.random () * 100);

} catch (interruptedexception ex) {

System.out.println ("Thread Interrupted");

System.out.println (ex.getstacktrace ());

}

}

}

}

// connumer

Public class consumer extends thread {

PRIVATE CUBBYHOLE HOLE;

Public consumer (cubbyhole hole) {

THIS.HOLE = Hole;

}

Public void run () {

For (int i = 0; i <10; i ) {

System.out.println (hole.get ());

}

}

}

In this example, the producer and the consumer share public resources - Cubbyhole objects. In the above program, synchronization problems will occur between the Producter and the Consumer thread. If the product generates the data speed greater than the Consumer getting speed or the consumer getting speed is greater than the producter production speed, the result of consumer acquisition is incorrect. In fact, what we need is that the data obtained by consumer is the data generated by Producer.

The activities of Producter and Consumer must be synchronized in two ways.

First, the two threads must not access the CubbyHole object at the same time. This can be prevented from occurring by locking the object in the Java thread. When an object is locked by a thread, the second thread attempts to call the synchronization method of the object, the second thread will be blocked until the object is unlocked.

Second, the two threads must do some simple cooperation. That is, the product must notify the consumer data through some way to prepare the consumer must tell the product of the data has been acquired. Thread class provides WAIT, Notify, and NotifyAll methods to help thread wait conditions and notify other threads when the condition changes

Lock object

Critical sections

The Critical section in Java can be a block or a method with a synchronized keyword in Java.

In the Producter / Consumer example, when Producer changes the CubbyHole object, Consumer cannot access the CubbyHole object; Producer cannot change the CubbyHole object when consumer read the CubbyHole object. Therefore, the PUT and GET methods of the CubbyHole object should be declared as critical sections.

Public class cubbyhole {

PRIVATE INT CONTENTS;

Private boolean available = false;

Public synchronized int GET () {

...

}

Public Synchronized Void Put (int value) {

...

}

}

Whenever a thread enters a synchronization method, other threads cannot call the synchronization method of the object until the object unlocks. Therefore, when Producer calls the PUT method, the CubbyHole object is locked to prevent the CubbyHole's GET method. When the PUT method returns, the Coubyhole object is unlocked.

Public synchronized int GET () {

// cubbyhole locked by the consumer

...

// cubbyhole unlocked by the consumer

}

The lock and unlock are automatically implemented by the Java running system to ensure the integrity of the data. However, just rely on synchronization, the two threads must notify each other's their respective work has been completed.

NotifyAll and WAIT methods

Add a private Boolean member variable in the CubbyHole object. When Available is true, the data is allowed to obtain data; the write data is allowed to be written to FALSE. Simple implementation is as follows:

Public synchronized int GET () {

IF (Available == True) {

Available = false;

Return Contents;

}

}

Public Synchronized Void Put (int value) {

IF (available == false) {

Available = True;

CONTENTS = VALUE;

}

}

In fact, the above two methods will not work properly. When Producer has not produced data, the Available cannot be true. Similarly, when the product is called the PUT method before consumer acquisition data, the PUT method does nothing. Therefore, consumer must wait for the product to put the data into the cubyhole and notify the consumer already put into data. Similarly, Producer must wait until the consumer takes the data and inform it to place new data into the cubbyhole. The two threads can be done by the WAIT and NotifyAll methods of the object. The PUT and GET methods are modified as follows: public synchronized int get () {

While (available == false) {

Try {

// Wait for Producter to Put Value

Wait ();

} catch (interruptedexception e) {

}

}

Available = false;

// Notify Producer That Value Has Been Retrieved

NotifyAll ();

Return Contents;

}

Public Synchronized Void Put (int value) {

While (Available == True) {

Try {

// Wait for consumer to get value

Wait ();

} catch (interruptedexception e) {

}

}

CONTENTS = VALUE;

Available = True;

// Notify Consumer That Value Has Been Set

NotifyAll ();

}

In the GET method, it is loop until the product is generated, and the WAIT method is called each cycle. WAIT method Abandon lock CubbyHole objects, allowing ProductER to lock and update the CubbyHole object and wait for the product notification. When Producer updates the Cubbyhole object, call the NotifyAll method to notify consumer. Then consumer exits the WAIT status, AVAILABLE is true, exit the loop, and the GET method returns the value. Similarly, the PUT method waits for the CONSUMER thread to get the current value.

The NotifyAll method wakes all the processes waiting for the same object (Cubbyhole), the wake-up process competition, after a thread gets the lock, other threads returns waiting. Object classes can also define a Notify method to specify a wake-up thread

Java defines a wait () and notify () method in class java.LANG.Object, calling them, can also achieve synchronization between threads.

Important: You can use the SLEEP method to replace the WAIT method. However, the WAIT method can wake up with the Notify method and the SLEEP must wait until the time is over.

■ Public Final Void Wait (Long Millseconds) THROWS InterruptedException

When this method is called, the object is adjusted into the waiting state until it is awakened or waiting time.

■ Public Final Void Notify () Wakes an object that is waiting within an object.

■ Public Find Void Allotify () wakes up all objects in an object.

Thread priority and scheduling

Since the computer we generally use is a single CPU, thread scheduling is required when executing multithreaded programs. Thread scheduling is determined by the priority of the thread. High priority threads always run first. Java uses a preference to schedule, that is, when the high priority thread enters the runnable state, the location of the low priority thread is preempting and start executing. When two or more threads have high priority and enter the operational state, Java's scheduling will automatically perform alternately on these threads. In Java, three constants are predefined in the Thread class:

Max_Priority, Min_Priority, Norm_Priority,

The priority of a thread should be between Max_Priority and Min_Priority. NORM_PRIORITY is the default priority value, typically min_priority and max_priority average.

In Java, the Thread class provides method settings and get priority.

SetPriority (int) Used to set the priority number of threads

SetPriority () used to get the priority of threads

Thread group

The thread group is an object set including many threads. Each thread has its own specific thread group. A thread is a thread group when it is created until it is completed, and this thread cannot change its thread group. The constructor is provided in the THREAD class to make the creating threads simultaneously determine their thread groups. The Thread class provides a total of six constructors:

Thread ();

Thread (String);

Thread (Runnable);

Thread (Runnable, String);

Thread (ThreadGroup, String);

Thread (ThreadGroup, Runnable, String);

The first four default thread groups, indicating that the created thread belongs to the main thread group, and then two thread groups of the threads created. Threads can access your own thread group, but you cannot access the parent class of this closing group. The operation of the thread group is to operate simultaneously on the respective threads in the thread group.

Construction method of thread group:

ThreadGroup (String Groupname)

Create a thread group named GroupName, the parent class of the thread group is the program where the current thread is located.

ThreadGroup (ThreadGroup Parent, String Groupname)

Create a thread group named GroupName, the parent class of the thread group is Parent.

-------------------------------------------------- ---------- Multi-threaded point ------------------------------------- ---------------------------------------

1. There is a master memory and work memory in multi-threads. In JVM, there is a primary memory, which is responsible for all thread sharing data; and each thread has his own private work memory, main memory and work memory scores The Stack area of ​​JVM and the HEAP area.

2. The state of the thread has 'Ready', 'Running', 'Sleeping', 'Blockd', and 'Waiting' Several Status

3. Thread run order is not running according to the order when we create them, the order in which the CPU handling thread is uncertain. If you need to be determined, then you must manually intervene, use the setPriority () method to set the priority.

4. We don't know when a thread is running, two or more threads need synchronized when accessing the same resource.

5. Each thread will register yourself, there is actually a reference to it, so the garbage collection mechanism is "helpless".

6. The DAEMON thread differences general thread is: Once the main program ends, the daemon thread will end. 7. All SYNCHRONIZED methods in an object share a lock, which prevents multiple methods from writing simultaneously for universal memory. The Synchronized Static method can be locked in a class range.

8. For all methods accessing a key shared resource, you must set them to synchronized, otherwise it will not work properly.

9. Suppose a method is known that a method does not cause conflicts, and the most sensible method is not to use Synchronized to improve some performance.

10. If a "synchronization" method modifies a variable, and our method uses this variable (probably only read), it is best to set your own method to synchronized.

11. Synchronized cannot inherit, the method of the parent class is synchronized, then "synchronization" is not inherited in its subclass overload method.

12. Thread block blocked has several reasons:

(1) Thread waiting for some IO operation

(2) The thread attempts to call another object's "synchronization" method, but that object is locked, temporarily unable to use.

13. Atomic operation (atomic), the operation of the primitive variable is atomic atomic. It means that these operations are threads, but in most cases, we don't use it correctly, come and see I = i 1, i is an INT type, which belongs to the original variable:

(1) Read the I value from the main memory to the local memory.

(2) Load the value from the local memory to the thread work copy.

(3) Load variable 1.

(4) Plus I plus 1.

(5) The result is given the variable I.

(6) Save i to the thread local working copy.

(7) Write back the main memory.

Note that atomic operation is limited to the reading of steps 1 to 2, and the value of I = I 1 is also executed simultaneously (in step 4). . Double and long variables are non-ATOMICs. The array is an Object non-atomic type.

14. For 13 reasons, our solution is:

Class XXX EXTENDS THREAD {

// I will be modified frequently

Private INT i;

Public synchronized int} {returni}

Public synchronized void update () = i 1;}

........

}

15. Volatile variable, volatile variable indicates that it must be consistent with the main memory, it is actually "synchronization of variables", that is, for the operation of the Volatile variable is atomic, such as before the long or double variable.

16. Use Yield () to automatically discard the CPU, sometimes more improved than SLEEP.

17. The difference between SLEEP () and WAIT () is that the wait () method is called when it is called, but we can use it just in a synchronized method or code block.

18. By manufacturing a reduced synchronization range, the code block synchronization is achieved as much as possible, WAIT (Mix) can exit Wait at the specified millisecond; for Wait () needs to be woken up by Notisfy () or NotifyAll ().

19. Constructing a method of real-time communication between two threads:

(1). Create a PIPEDWRITER and a PiPedReader and the pipeline between them;

PipedReader in = New PipedReader (New PiPedWriter ())

(2). Before the thread that needs to send information, the external PiPedWriter will give the external PiPedWriter to the Writer instance OUT.

(3). Before the thread that needs to accept information, the external PiPedReader is guided to the Reader instance IN (4) of the inside. This is to be extracted from in IN.

20. Synchronized has a decline in the problem that the biggest shortcoming will bring deadlocks, only to prevent deadlocks by cautious design, and there is no way, this is a reason why threads are difficult to tame. Don't use STOP () Suspend () Resume () and Destory () method

21. When a large number of threads are blocked, the highest priority thread runs first. But do not mean that the low-level thread will not run, and the probability is small.

22. The main advantage of the thread group is that the operation of the entire thread group can be done using a single command. A thread group is rarely needed.

23. Enhance multithreading performance from the following aspects:

Check all possible blocks of Block, using Sleep or Yield () and Wait () as much as possible.

Extend the time of SLEEP (millisecond) as possible;

Running threads do not have to exceed 100, and it is not too much;

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

New Post(0)