Java multi thread programming core technology (notes)

Multithreading is asynchronous (asynchronous, i.e., synchronized, ReentrantLock, etc.), and the time when the thread is called is random.
 
There are two ways to use multithreading: inherit Thread and implement the run method under Runnable interface.
ThreadThe class implements the Runnable interface, which has polymorphic relationships.
A thread is a sub task, and CPU runs in an uncertain way.
 
Thread.startMethod tells the thread planner that the thread is ready to wait for the run method of the thread object to be called.
If the Thread.run method is invoked, it is not executed asynchronously, but is synchronized. Then the secondary thread object is not handled by the thread planner, but by the main main thread calling the run method, which means that the code in the run method must be executed before it can execute the followingCode.?????
Thread.run()Returns the name of the main main thread of Thread.currentThread ().GetName ().
Thread.start()Returns the name of Thread.currentThread ().GetName () similar to Thread-0.
 
 
 
 
Custom instance variables in thread classes can be shared or shared by other threads:
Sharing data is that multiple threads can access the same variable.
 
synchronizedYou can lock any object or method, and this code for locking can be called a “mutex” or “critical”.
 
When a thread wants to execute the code in the synchronization method, it first gets the lock and then executes the code in the code block.
 
currentThreadMethod can return information that the code segment is being called by those threads.
The name of the main main thread of Thread.currentThread ().GetName () in the common method of the thread class.
Thread-0 thread names like this. currentThread (). getName () in the normal method of a thread class (even if set by thread. setName (“A”) return Thread-like names-0 such thread names;
Thread. currentThread (). getName () in the run method of the thread class is either a Thread – 0 like thread name or a custom thread name (via thread. setName (“A”));
Thread-0-like thread names in the run method of this. currentThread (). getName () in the thread class (even if set by thread. setName (“A”) return Threa-like namesD-0 such thread names);
 
isAliveMethod: to determine whether the current thread is active.
Active state: A thread that has been started and has not yet terminated is called active state (running or running state).
 
sleep()Method: The effect is to let the currently executing thread sleep (pause execution) within milliseconds of execution, which is the thread returned by this. currentThread ().
 
getIdMethod: when the thread name of the current executing code is main, the thread Id returned is 1.
 
 
There are three ways to stop threads:
Use the exit flag to make the thread exit normally, that is, when the run method completes, the thread terminates.
Using the stop method to forcibly terminate threads is not recommended because stop, like suspend and resume, is an expired method that can produce unexpected results.
Thread.interrupte()Method interrupt threads.
 
 
Thread.interrupte()The method stops the running thread, but not immediately. When the Thread. interrupte () method is called,It is only a stop sign for the current thread, and it is not stopping.
 
 
There are two ways to determine whether a thread is stopped: this.interrupted () and this.isInterrupted ();
this.interrupted():Test whether the current thread has been interrupted. (static method), the interrupted method will interrupt the flag. When calling the interrupted method several times, it will return true only for the first time.
this.isInterrupted():Whether the test thread has been interrupted. (Normal method), the isInterrupted () method does not clear the interrupt status flag, and returns true when the interrupted method is called many times.
 
sleepMethod, if the thread is interrupted in hibernation, it will report error.
 
 
Thread exit: The thread invokes the interrupt interrupt method, and then uses the interrupted method to determine if the thread interrupt flag is true. If true, the interrupt interrupt method is invoked on behalf of the current thread, and then there are two kinds of interrupt methodsOne option is to use return to return, and the second way is to throw exceptions in the way of throw exceptions.
 
 
suspendThe disadvantage of the resume method is that if used improperly, it may cause the common resource synchronization object to be exclusive, making it impossible for other threads to access the common synchronization object.
 
 
yieldMethod: the effect is to give up the current CPU resources, it will be given to other tasks to occupy CPU execution time, but the abandoned time is uncertain, may just give up, and immediately get the CPU time slice.
 
Thread priority is inherited, such as when thread A starts thread B, and thread B has the same priority as thread A.
Thread priority is random, that is, threads with high priority are not always executed first.
 
The private variables inside the method, which are never thread-safe, are always thread-safe because the variables inside the method are private.
 
Instance variables are non-thread-safe, and non-thread-safe problems may occur when multiple threads access instance variables of the same object.
 
synchronizedThe object lock is achieved rather than a piece of code or a method as a lock.
The way to call synchronized must be queued up.
 
AThreads hold Lock locks on object objects first, and B threads can call asynchronously methods of non-synchronized types in object objects
AThe thread holds the lock lock on the object object object first, and if the B thread calls a method of the synchronized type in the object object object at this point, it needs to wait, that is, synchronize.
Multiple synchronized methods for an object have unique object locks.
The method that adds synchronized must be executed synchronously, for example, after object A executes the synchronized method, other synchronized methods of object A can be executed. Or synchronize in the execution of an object.The D method must wait for the execution of the method.
 
synchronizedLocks can be reentrant: the synchronized method of object A can call other synchronized methods in A objects.
Lock reentrant can also be applied to the synchronized method call of father child relationship.
 
synchronizedWhen an exception occurs, the lock will be released automatically.
 
synchronizedSynchronization does not inherit, so object A cannot inherit the synchronized method of the parent class.
 
Different synchronized blocks in the same object use the same lock.
 
The synchronized block in the same object uses the same lock as the synchronized method.
 
synchronizedCode block parameters can use non-this parameters, i.e. variables of objects or parameters of methods (variables must be variables of objects, not local variables within methods)
 
Method A’s synchronized method and method B’s (non-this parameter) synchronized code block thread in the same object are insecure
 
synchronizedWhen you add a static method to a class, you lock it; when synchronized loads a non-static method, you lock the object
 
synchronizedIf two methods in an object have a block of code and the parameter is not this, the two methods execute asynchronously, i.e. when two threads call two methods, both methods execute simultaneously.
 
volatileThe role of keywords is to force the values of variables from the public stack, not from the thread private data stack.
Using the volatile keyword increases the visibility of instance variables between threads, but the volatile keyword does not support atomicity.
The keyword volatile is a lightweight implementation of thread synchronization, and all volatile performance is definitely better than synchronized, and volatile only modifies variables, while synchronized modifies methods and blocks of code.
Multithreaded access to volatile will not block, and synchronized will block.
volatileIt guarantees data visibility, but not atomicity, and synchronized guarantees atomicity and indirect visibility because it synchronizes data in private and public memory.
volatileKeywords are used to solve the visibility of variables between multiple threads.
synchronizedThe key to solve the problem is to synchronize resources between threads.
 
The keyword synchronized allows multiple threads to access the same resource synchronously, and it also has the ability to synchronize private variables in thread working memory with variables in public memory.
 
sleepAnd yield is Thread’s method.
waitNotify is a object class method.
waitRelease lock, notify lock does not release
notifyThe operation attempts to wake up a thread that is removed from the blocked state by calling the wait operation, and if there is no thread in the blocked state, the command is ignored.
 
waitMethod causes the thread calling the method to release the shared resource, then exit from the running state and enter the wait queue until it is waked up again.
 
waitThe notify must be called in the synchronized synchronized method or in the synchronized block. If the notify and wait are called without a lock, an error is reported. After the notify method is executed, the current thread does not immediately release the object lock, and the thread in the wait state does notYou can’t get the lock of the object immediately, and you won’t release the lock until the thread of the notify method executes.
 
Each lock object has two queues, one is the ready queue (which stores the thread that will get the lock), the other is the blocking queue (which stores the blocked thread), and the wait and notify can be threads that convert between the ready queue and the blocking queue.
 
Communication between threads through channels: byte streams, after the call is completed, the close method needs to be executed.
PipeInputStream、PipeOutStream
PipeWrite、PipeRead
 
The role of join is to wait for thread object to be destroyed.
In the process of calling join, if the current thread object is interrupted, the current thread is abnormal.
joinThe method waits internally using the wait method, while the synchronized keyword uses the “object monitor” principle to do his synchronization.
The method join allows the thread object X to execute the task in the run method normally, blocking the current thread x indefinitely, waiting for thread x to destroy before continuing to execute the code after thread Z.
 
join(Long)Set wait time
 
joinUnlike sleep, join methods are implemented internally using wait methods, and all join methods have the specificity of releasing locks. The Thread.sleep () method cannot release the lock.
 
 
ThreadLocal:The main solution is that each thread binds its own value, and the ThreadLocal class can be likened to a box that stores data globally, in which private data for each thread can be stored.
The ThreadLocal variables set by their threads in multiple threads are independent.
 
InheritableThreadLocalYou can get the InheritableThreadLocal value set in the parent thread in the child thread.
If you need to modify the value obtained in the parent thread in the child thread, you can inherit the InheritableThreadLocal class and modify the value obtained in the parent class in the childValue method.
However, it is important to note that if the parent thread changes the value when the child thread gets the parent class InheritableThreadLocal worth it, the InheritableThreadLocal value obtained by the child thread is still the old value.
 
 
ReentrantLock
Call the lock () method of the ReentrantLock object to get the lock and call the unlock method to release the lock.
lockThe thread of the method holds the object monitor.
 
ReentrantLockUse Condition to implement waiting and notification.
synchronizedWhen threads execute notifyAll, you need to notify all waiting threads. Without choice, there will be considerable efficiency problems.
ConditionBefore an object calls the await () method, it must execute the lock method of the ReentrantLock object, or it will report an error. (it is necessary to get the synchronization monitor before executing the await method).
ConditionThe signal of the class corresponds to await. Similar to Object class wait and notify.
If a ReentrantLock class gets more than one Condition object, it can wait or wake up the specified Condition object depending on the Condition.
 
 
Fair locks and unfair locks
Lock Lock is divided into fair locks and unequal locks. Fair lock is that the order in which the thread acquires the lock is allocated according to the order in which the thread adds the lock, i.e. FIFO FIFO FIFO FIFO FIFO FIFO FIFO FIFO FIFO FIFO FIFO FIFO FIFO FIFO FIFO FIFO FIFO FIFO FIFO FIFO FIFO FIFO FIFO FIFO FIYou don’t have to get the lock first. This may cause some threads to never get the lock, which is unfair.
ReentrantLockFair and unfair locks are set by constructing parameters, defaulting to fair locks and ReentrantLock (false) to unfair locks.
ReentrantLockThe getHoldCount method of the class looks at the number of times the current thread holds the secondary lock, that is, the number of times the lock method is called (for lock nesting, where there is a lock method in method A, and method A calls method B, and method B calls the lock method as well.In the A method, getHoldCount returns 1, and getHoldCount returns 2 in the B method.
 
ReentrantLockThe getQueueLength method of the class is to return the thread counter waiting for this lock.
 
ReentrantLockThe getWaitQueueLength (Condition condition) function of the class is to return an estimate of the thread waiting for a given condition condition condition associated with this lock, such as five threads, each executing the same ConditThe await method of the ion object returns the int value of 5. when calling the getWaitQueueLength method.
 
hasQueueThreadThe function is to find out whether the specified thread is waiting for this lock.
hasQueueThreadsThe function is to query whether there is a thread waiting for this lock.
hasWaitersThe function is to query whether there is a thread waiting for the Condition condition related to this lock.
isFair()Is it a fair lock?
isHeldByCurrentThread()See whether the current thread maintains this lock.
isLockedThe function is to check whether the lock is maintained by any thread.
 
void lockInterruptibly()The purpose is to get the lock if the current thread is not interrupted, and return an exception if it has been interrupted (that is, the thread called the interrupt method).
 
boolean tryLock()The function of this method is to get the lock only when the call is locked without being kept by another thread.
 
awaitUntil(Calendar.getTime())The effect is to wait for the code to arrive at the specified time, after the start of the execution, the method can be notify or notifyAll wake up, that is, not reaching the specified time can also get the lock, continue to execute the subsequent code.
 
ReentrantReadWriteLockMultiple read threads of a class can share locks, but all threads are mutexes as long as there is one write thread in multiple threads.
 
Timertimer
public class Test {
public static class TaskService extends TimerTask {
@Override
public void run() {
System.out.println(“Start running “+System.currentTimeMillis ());
}
}
public static void main(String[] args) throws ParseException {
//Timer timer = new Timer();
Timer timer = new Timer();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”);
TaskService taskService = new TaskService();
timer.schedule(taskService,simpleDateFormat.parse(“2017-02-27 22:13:10”));
}
}
 
The scheduled execution time is earlier than the current time, and the Task task is executed immediately.
TimerTaskIt is queued one by one, so the execution time may be inconsistent with the expected time, because the previous task may take longer, and the subsequent task may be delayed.
 
schedule(TimerTask task,Date firstTime,long period)The function of the method is to perform a task periodically and infinitely after a specified date, at a specified interval of time. The period parameter is interval time (milliseconds).
 
TimerTaskThe cancel method of a class removes itself from the task queue. Other tasks will not be affected.
public class Test {
public static class TaskServiceA extends TimerTask {
@Override
public void run() {
System.out.println(“AStart running “+System.currentTimeMillis ());
this.cancel();
}
}
public static class TaskServiceB extends TimerTask {
@Override
public void run() {
System.out.println(“BStart running “+System.currentTimeMillis ());
}
}
public static void main(String[] args) throws ParseException {
//Timer timer = new Timer();
Timer timer = new Timer();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”);
TaskServiceA taskServiceA = new TaskServiceA();
timer.schedule(taskServiceA,simpleDateFormat.parse(“2017-02-27 22:13:10”),1000);
TaskServiceB taskServiceB = new TaskServiceB();
timer.schedule(taskServiceB,simpleDateFormat.parse(“2017-02-27 22:13:10”),1000);
}
}
AStart running 1488209066938
BStart running 1488209066939
BStart running 1488209067939
BStart running 1488209068965
BStart running 1488209069965
BStart running 1488209070965
…..
 
 
TimerThe cance method of the class is to empty all the tasks in the task queue.
public class Test {
public static Timer timer = new Timer();
public static class TaskServiceA extends TimerTask {
@Override
public void run() {
System.out.println(“AStart running “+System.currentTimeMillis ());
timer.cancel();
}
}
public static class TaskServiceB extends TimerTask {
@Override
public void run() {
System.out.println(“BStart running + + System.currentTimeMillis ();
}
}
public static void main(String[] args) throws ParseException {
//Timer timer = new Timer();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”);
TaskServiceA taskServiceA = new TaskServiceA();
timer.schedule(taskServiceA,simpleDateFormat.parse(“2017-02-27 22:13:10”),1000);
TaskServiceB taskServiceB = new TaskServiceB();
timer.schedule(taskServiceB,simpleDateFormat.parse(“2017-02-27 22:13:10”),1000);
}
}
AStart running 1488209178347
 
TimerThe purpose of the class’s can method is to empty out all the tasks in the task queue, but sometimes it doesn’t necessarily stop executing the scheduled tasks, but to continue to execute the tasks normally, because Timer’s cancel method doesn’t get the queue lock.
Source code:
public void cancel() {
synchronized(queue) {
thread.newTasksMayBeScheduled = false;
queue.clear();
queue.notify(); // In case queue was already empty.
}
}
 
 
schedule(TimerTask task,long delay)The function of the method is to perform a TimerTask task after deferring a specified number of milliseconds based on the current time as the reference time.
 
The schedule and scheduleAtFixRate methods are executed sequentially without considering non-thread security issues
The main difference between schedule and scheduleAtFixRate is that there is no delay.
Method schedule If the execution time of the task is not delayed, the execution time of the next task is calculated by reference to the start time of the last task.
scheduleAtFixRateMethods If the execution time of a task is not delayed, the execution time of the next task is calculated by referring to the end time of the last task.
 
 
Thread.sleep()After execution of the method, enter the TIMED_WAITING state.
BLOCKEDBlocking occurs when a thread is waiting for a lock.
WAITINGState is the state after Object.wait () method.

Leave a Reply

Your email address will not be published. Required fields are marked *