Threads have overhead time for creation and context switching, and all single-threaded programs are not necessarily slower than multithreaded execution times. (the shorter the execution time is, the more obvious it is).
In imperative programming, there are two communication mechanisms between threads: shared memory and message passing.
In shared memory concurrency model, threads share common status.
In message passing concurrency model, messages must be displayed between threads.
Synchronization must be displayed in the shared memory model, such as synchronized, and synchronization is implicit in the message synchronization mechanism.
JavaConcurrency is a shared memory model.
Heap memory is shared online.
Local variables, method definition parameters, exception handling parameters are no longer shared between threads, they do not have memory visibility problems, and they are not affected by the memory model.
Shared variables between threads are stored in main memory, and each thread has a private local memory in which copies of read and write shared variables are stored.
DaemonThread: when Java virtual machine does not exist non Daemon thread, the Java virtual machine will exit.
You can set the thread to Daemon thread through Thread.setDaemon (true).
JavaWhen the virtual machine exits, the finally block in the Daemon thread is not necessarily executed.
Starting the thread start method means that the current thread synchronously tells the Java virtual machine that the thread calling the start method should be started as soon as the thread planner is free.
InterruptInterrupt: Interrupt can be understood as a marker bit property of a thread, which is whether a running thread has been interrupted by other threads.
If the thread calls interrupt interrupt in the state of sleep or wait (not running), it will report an error.
Expired suspend () pause, resume () recovery, stop () stop three methods:
It is not recommended to use the suspend method when it should be called, the thread will not release the occupied resources that lock, but occupy the resources into a sleep state, which is easy to cause deadlocks.
stopMethods end a resource without guaranteeing the normal release of the thread’s resources, usually without giving the thread the opportunity to complete the release of resources, so that the program may work in an incorrect state.
Secure termination of threads: Boolean identifiers can be added to the thread class to control whether code in the run method is executed.
public class Test {
public static void main(String[] args) {
PrintClass.flag = true;
Thread thread = new Thread(new PrintClass());
thread.start();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
thread.interrupt();//Pause thread execution
thread = new Thread(new PrintClass());
thread.start();
PrintClass.flag = false;//Thread of execution execution
}
static class PrintClass implements Runnable {
public static volatile int i =1;
public static volatile boolean flag =false;
@Override
public void run() {
while(flag&&!Thread.interrupted()) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(i++);
}
}
}
}
volitileKeyword is used to modify variables, informing the program that any access to the variable needs to be obtained from shared memory, and that changes to the variable must be synchronously refreshed to the shared memory, which ensures that all threads have visibility of the variable access.
synchronizedKeyword can be used in the form of modifier method and synchronization block. It mainly ensures that only one thread can be in the method or synchronization block at the same time. It ensures the visibility and exclusiveness of thread access to variables.
Any object has its own monitor. When the object is called by a synchronization fast or synchronization method of the object, the thread that executes the method must first get to the monitor of the object to enter the synchronization fast or synchronization method, and the thread that does not get to the monitor will be blocked on the synchronization block or synchronization side.The entrance to the law enters the BLOCKED state.
For any thread to access Object (decorated by synchronized), the first step is to get the Object monitor. If the capture fails, the thread enters the synchronization queue and the thread state becomes BLOCKED. When accessing Object’s predecessor (get the thread of the lock)If the lock is released, the release operation wakes up the thread blocking the synchronous queue and makes it try again to get the monitor.
Waiting and notification mechanisms are available to any Java object because these methods are defined on the superclass Object of all objects, including:
wait:The thread that invokes this method enters the waiting state, and returns only when it waits for notification from another thread or is interrupted. Note that calling the wait method releases the lock on the object.
notify:Notifies a thread that is waiting on an object to return from the wait method, provided that the thread gets the lock on the object.
notifyall:Notifies all threads waiting for that object.
wait(long):The supermarket waits for a period of time, where the parameter time is milliseconds, that is, up to n milliseconds, and returns overtime without notice.
wait(long,int):For fine-grained control of timeout time, nanoseconds can be achieved.
Waiting and notification mechanism is that one thread A calls the wait method of object O into the wait state, while another thread B calls the notify or notifyAll method of object O. After receiving notification, thread A returns from the wait method of object O to perform subsequent operations. upperThe relationship between the wait method and the notify or notifAll method on the object is used to complete the interaction between the waiting party and the notifying party just like the switching signal.
notifyOr when the notifyAll method is executed, the thread that calls the wait method does not execute immediately. The waiting state thread can execute only after the notify or notifyAll method releases the lock.
notifyIn the method, a waiting thread in the waiting queue is moved from the waiting queue to the synchronous queue.
notifyAllThe method is to move all the threads in the wait queue to the synchronous queue and change the state of the moved thread from waiting to blocked.
The wait / notification mechanism relies on synchronization to ensure that the waiting thread is aware of the changes made by the notification thread when it returns from the wait method.
Pipeline input / output stream
Pipeline input and output streams differ from ordinary file input and output streams or network input and output streams in that they are mainly used for data transmission between threads, and the transmission medium is memory.
It includes: flow oriented to byte and object.
PipeInputStream、PipeOutputStream
PipeReader、PipeWriter
public class Test {
public static void main(String[] args) throws IOException {
PipedReader pipedReader = new PipedReader();
PipedWriter pipedWriter = new PipedWriter();
pipedReader.connect(pipedWriter);
Thread thread = new Thread(new ReadClass(pipedReader));
thread.start();
int receive = 0;
while((receive = System.in.read())!=-1) {
pipedWriter.write(receive);
}
}
static class ReadClass implements Runnable{
private PipedReader pipedReader;
public ReadClass(PipedReader pipedReader) {
this.pipedReader = pipedReader;
}
@Override
public void run() {
int receive = 0;
try {
while((receive = pipedReader.read())!=-1) {
System.out.print((char)receive);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Thread.join()Use
If thread A executes the thread. join () method, it means that the current thread A waits until the thread terminates before returning from thread. join ().
When thread A finishes executing the join, it calls the notifyAll method of the thread itself (implemented in the JVM at the time of the call, which is not visible in all JDKs), and notifies all the threads waiting on the thread object.
ThreadLocalThread variable is a ThreadLocal object as the key, any object is worth the storage structure, this structure is attached to the thread, that is, a thread can query through a ThreadLocal object to a value bound to the thread.
JavaConcurrent framework and container
ConcurrentHashMapIt’s a thread safe and efficient HashMap.
HashMapDeadlock loops occur when put operations are executed concurrently because multithreading causes the Entry list of HashMap to form a ring data structure. Once a ring data structure is formed, the next node of Entry is always empty and a dead loop is created to obtain Entry.
HashTableContainers use synchronized to ensure thread safety, but HashTable is inefficient when threads compete fiercely because when one thread accesses the synchronized synchronized method of HashTable, other threads also access HAshTable’s synchronization method enters a blocking or round robin state. If a thread puts, other threads not only can’t put, but also can’t get.
ConcurrentHashMapUsing lock segment technology can effectively enhance concurrent access rate.
HashTableThere is only one object lock in it, but ConcurrentHashMap uses multiple locks and does not lock part of the data, so when multithreads access data from different data segments in ConcurrentHashMap, there will be no lock contention between threads, thus effectively mentioningHigh concurrent access efficiency.
ConcurrentHashMapThere are Segments and HashEntry arrays, Segments act as re-locking, and each ConcurrentHashMap contains a set of Segments, each Segment is used to lock one of the HashEntry arraysWhen modifying the data in the HashEntry array, the Segment lock corresponding to the data is first obtained.
Hash collisions can be reduced by re-hashing the data evenly distributed to the HashEntry array list.
Java13 atomic operation classes in
Three basic types: AtomicInteger, AtomicLong, AtomicBoolean
Explain the compareAndSet (int expect, int update) method: the first step is to get the value in Atomic Integer, the second step is to add one to the value in Atomic Integer, and the third step is to check whether the current value is equal to CUrrent, which means that the value of Atomic Integer is not modified by other threads, updates the current value of Atomic Integer to the update value, and returns false if not.
Atomic update array
AtomicIntegerArray、AtomicLongArray、AtomicReferenceArray
For example:
int[] value = {1,2};
AtomicIntegerArray ai = new AtomicIntegerArray(value);
Atomic update reference type
AtomicReference
Atomic update field class
AtomicIntegerFieldUpdater、AtomicLongFieldUpdater、AtomicStampedFieldUpdater
For example:
//You must use the newUpdater static method to create a newer and set the class and attribute that you want to update.
AtomicIntegerFieldUpdater<User> a = AtomicIntegerFieldUpdater.newUpdater(User.class,”old”);
User userA = new User(“Allen”,10);
a.getAndIncrement(userA);//oldValue added by one
When A.get (userA) is exported, the old value is changed to 11..
CountDownLatch:Allows one or more threads to wait for other threads to complete the operation.
Initialization: can only initialize once, and can not modify the counter value.
countDown()The method does not call once, and the counter is reduced to 0..
await()Method will block the execution of the current program until the counter is 0.
CountDownLatch countDownLatch = new CountDownLatch(2);
CyclicBarrierClasses block a set of threads when they reach a barrier, and the barrier does not open until the last thread reaches the barrier, and all the blocked threads continue to execute.
CyclicBarrier c = new CyclicBarrier(2);
Call the await method to tell CyclicBarrier that I have reached the barrier and the current thread is blocked.
If some threads do not reach the barrier (that is, calling the await method), the thread is blocked.
CyclicBarrierIt also provides an advanced constructor, Cyclic Barrier (int partis, Runnable barrier Action), to prioritize barrier actions when threads reach the barrier, facilitating more complex business processesThe scene.
CountDownLatch Unlike Cyclic Barrier, Cyclic Barrier can be reset and CountDownLatch’s counter can only be used once.
SemaphoreClass is used to control the number of threads that access a particular resource at the same time. It coordinates threads to ensure the rational use of public resources.