Concurrent programming three

   Lock

      The interface introduced by the concurrent package of Java5: java.util.concurrent.locks, its function is similar to that of synchronize, calling the lock() method at the beginning of the code to acquire the lock, and calling unlock() at the end to release the lock.

 

public class MainClass
{
    private Lock   lock;
 
    private Object shared;
 
    public void operation()
    {
        lock.lock(); //Obtain the lock, if it cannot be obtained, the thread will enter an uninterruptible wait state
        try
        {
            operate( shared ); //Operate shared resources
        }
        finally
        {
            lock.unlock(); //release the lock
        }
    }
}

 The lock interface provides more detailed control methods than the synchronize keyword. It provides the following methods

 

  1.      lock() : acquire the lock
  2.      tryLock() : try to acquire the lock, if the lock is not acquired, return false directly without waiting
  3.      tryLock( Long time, TimeUnit unit ) : Try to acquire the lock, if the acquisition is unsuccessful and wait, the lock is acquired during the waiting time, return true, otherwise return false. Can respond to interrupt exceptions
  4.      lockinterruptibly(): try to acquire the lock, wait when the lock cannot be acquired, when the thread is waiting, you can call the interrupt method to interrupt the thread's waiting process.
  5.     unlock(): release the lock
  6.     newCondition() : Create a Condition object associated with this lock, Condition can replace Object.wait/signal/notify/notifyAll
  •      Reentrant lock: If the current thread already holds the lock L, then when calling another method that needs the lock, it does not need to release the lock again to acquire the lock, but ++ on the current lock count, and exit the method is On the count of locks --. This has the same semantics as the synchronize keyword. Not all lock implementations support reentrant semantics. ReentrantLock provides the following methods:
  •     Fair locks: As far as possible, acquire locks according to the request sequence of threads, that is, threads that wait for a long time acquire locks first, so as to avoid starvation. new ReentrantLock(true) can construct fair locks, which basically serve lock requesters in a first-in, first-out order. Developers can implement lock classes to implement other fair locking strategies. synchronize is an unfair lock.
  •     Read-write lock: The read-write lock divides the critical resources of the lock into consecutive parts, a read lock and a write lock. It is precisely because of the read-write lock that the multi-threaded read operation will not conflict. ReadWriteLock is a read-write lock, it is an interface, ReentrantReadWriteLock is its implementation, readLock() is to acquire a read lock, and WriteLock() is to acquire a write lock. In the absence of a write lock, multiple threads can acquire a read lock at the same time, but when there is a read lock or a write lock, the thread must wait for other threads to release the lock before acquiring it when acquiring the write lock.
  •     Statement Reflow: The JVM reflows statements without affecting semantics. This rearrangement does not consider concurrency.
private int i;
private int j;
public void set()
{
    //The order of the following two statements can be rearranged by the JVM
    i = 0;
    j = 1; // this statement can be reflowed anywhere in the method
    if ( i == 0 ) //The instruction with i = 0 must precede this sentence
        i = 1;
}

 This reordering of instructions may result in unexpected results under multithreading. So don't rely on the order of your code to avoid synchronization, a typical counter-example is the double-checking convention, the synchronize keyword prevents instruction reordering.

 In JSR-133, volatile semantics are enhanced, which prohibits reordering between volatile variables and ordinary variables. So after Java 5, volatile and synchronize have the same semantics - a read-write lock on a single variable.

Atomic class

   The concurrent package of Java 5 introduces several atomic classes, which support atomic operations, which can avoid synchronization and improve performance.

   The internal implementation of the Atomic family uses an optimistic locking mechanism: assuming that the current line has no shared variables that are repaired by other threads, and calculates the variables and new values, when trying to update the variables, check whether other threads repair the value, If there is, get the new value and repeat the calculation above.

thread priority

  1.   Thread priority 1-10, the higher the number, the higher the priority, the default priority is 5
  2.   The priority cannot guarantee the execution order of the threads, but the thread with high priority has a higher probability of obtaining CPU execution, and the thread with low priority does not have no chance to obtain
  3.   Determined by scheduling, which thread in the program executes
  4.   thread.setPriority() is used to set the thread priority
  5.   Setting the thread's priority should be done before calling the start() method
  6.   You can use constants to set the priority of the thread, such as: MIN_PRIORITY, MAX_PRIORITY, NORM_PRIORITY

 

 

Difference between yield and join methods

   yield() is the thread currently executed by the cpu, yielding the cpu and letting the waiting threads compete for the cpu, the current thread may reproduce the active cpu usage right and continue to execute

   join() means that the current main thread enters the waiting state and waits for the child thread to execute after the execution is completed.

 

thread state

    Initial : The initialization state, from the thread object is called until the start() method is called;

    Runnable: The thread is in the runnable state. The thread is in this state after calling the start() method. JDK provides many methods to allow the thread to change the Runnable state. The thread in this state does not necessarily occupy the CPU. In some cases, the Runnable state is subdivided. Runnable is waiting to obtain the CPU, and Running is the CPU that has been obtained and is executing.

    Blocked: The thread is blocked, and the thread in this state cannot run because it is waiting for some event to occur (timer, I/O), etc. The following conditions will enter the blocking state:

           Threads wait for I/O, such as reading sockets;

           Attempting to enter a critical section occupied by another thread (Synchronize) is blocked

           Attempting to block Locked occupied by other threads

           The sleep(), join() method or the Object.wait() method of the thread Thread is executed

      In some cases, the Blocked state is broken down as follows:

           Blocked: Waiting for the I/O thread to wait to enter the critical section;

           Waiting: call the Object.wait() method;

           Sleeping: call the Thread.sleep() method;

     Exiting: This state is entered once the thread returns from the run method, or the thread calls the stop method. In some cases, it is also in the Dead state.

           

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326034157&siteId=291194637