This article reprints le Byte

  1. Fundamentals of Multithreaded programming

1.1 Processes, threads 1.1.1 processes

Narrow sense: A process is an instance of a running program.

Generalized: A process is a program with some independent function, about a set of data running activity.

Process is the basic unit of dynamic execution in operating system. In traditional operating system, process is both the basic allocation unit and the basic execution unit.

1.1.2 thread

A thread is the smallest unit in which an operating system can debug operations. It is contained in the process and is the actual unit of action in the process. A thread is a single sequential flow of control in a process, and multiple threads can be concurrent in a process, each performing a different task.

1.1.3 Advantages of multi-threading

You can put tasks that take a long time in the background to make your application run faster

Returns details about the thread on which the code is being invoked

1.3.2 isAlive

Is to determine whether the current thread is active. The active state is when the thread is started and running without completion. A thread is considered alive if it is running or ready to start running.

1.3.3 sleep method

Suspends the current thread of execution for the specified number of milliseconds.

1.3.4 getId method

Gets the unique identity of the current thread

1.4 Stopping a thread Stopping a thread means ending the operation being performed before the thread processing completes the task.

Use exit flags to allow the thread to exit normally, that is, to terminate when the run method completes. Use a Boolean flag

The stop method forces the thread to stop (the stop method has been deprecated because forcing the thread to stop might prevent some rational work from being done. Another reason is that the locked object is “unlocked”, resulting in different data synchronization processing and data inconsistency.)

Interrupt a thread with the interrupt method

Calling the interrupt method does not actually terminate the thread; it marks the current thread with a stop flag. The Thread class provides the interrupted method to test whether the current Thread has been interrupted, and the isInterrupted method to test whether the Thread has been interrupted. Copy code image.png

1.5 Suspending a Thread You can suspend a thread and restart it using the resume method

public class Test { public static void main(String[] args) throws InterruptedException { Demo19Thread t = new Demo19Thread(); t.start(); Thread.sleep(1000);

t.suspend(); System.out.println("A=" + system.currentTimemillis () + ", I =" + t.geti ()); Thread.sleep(1000); System.out.println("A=" + System.currentTimeMillis() + ", i=" + t.getI()); t.resume(); Thread.sleep(1000); t.suspend(); System.out.println("B=" + System.currentTimeMillis() + ", i=" + t.getI()); Thread.sleep(1000); System.out.println("B=" + System.currentTimeMillis() + ", i=" + t.getI()); }Copy the code

}

class Demo19Thread extends Thread{ private long i = 0;

public long getI(){ return i; } public void setI(long i){ this.i = i; } @Override public void run() { while (true){ i++; }}Copy the code

} copy code image.png

The suspend and resume methods are both obsolete.

1. When the suspend method suspends a thread, the lock is not released. As a result, other threads cannot hold the lock and enter the run method.

2. The suspend and resume methods are not synchronized and may cause dirty read environments.

public class Test { public static void main(String[] args) throws InterruptedException { Demo22User user = new Demo22User(); Thread t1 = new Thread(){ @Override public void run() { user.updateUsernameAndPassword(“b”, “bb”); }}; t1.setName(“A”); t1.start();

Thread.sleep(10); Thread t2 = new Thread(){ @Override public void run() { user.printUseruserAndPassword(); }}; t2.start(); }Copy the code

}

class Demo22User { private String username = “a”; private String password = “aa”;

public void updateUsernameAndPassword(String username, String password){ this.username = username; If ("A".equals(thread.currentThread ().getName())){system.out.println (" stop Thread "); Thread.currentThread().suspend(); } this.password = password; } public void printUseruserAndPassword(){ System.out.println("username=" + username + ", password=" +password); }Copy the code

}

1.6 Yield Method The yield method is used to yield current CPU resources to other tasks. However, the abandonment time is uncertain. It is possible that the CPU time slice is acquired immediately after the abandonment.

1.7 Thread Priorities In the operating system, threads can be prioritized. Threads with higher priorities receive more CPU resources, so that the CPU performs tasks in the thread object with higher priorities first. Setting thread priority helps the Thread scheduler determine which thread is selected to execute first the next time.

The setPriority method is used to set the priority of a thread. The PRIORITY ranges from 1 to 10. If the priority is set to less than 1 or more than 10, the JDK throws IllegalArgumentException. The JDK defaults to three priority constants, MIN_PRIORITY=1(minimum), NORM_PRIORITY=5(median, default), and MAX_PRIORITY=10(maximum).

Get the priority of the thread using the getPriority method.

The priority of A thread is inherited. For example, thread A starts thread B, and thread B has the same priority as thread A. High-priority threads are always mostly finished first, but this does not mean that high-priority threads are all finished. When thread priorities vary widely, the order in which the code is called does not matter who finishes first.

Thread priority also has “randomness,” which means that the higher-priority line doesn’t always finish first

1.8 Daemon Threads There are two types of threads in Java threads, user threads and daemon threads.

A daemon thread is a special thread, special in the sense that it will destroy itself when no user thread exists in the process. A typical example of a daemon thread is the garbage collector thread. When there are no user threads in the process, the garbage collector thread is no longer necessary and will be destroyed automatically. (Settings daemon thread must be set before call the start method, otherwise the JDK will produce IllegalThreadStateException)

  1. Synchronization mechanism for threads

2.1 If multiple threads simultaneously read and write shared variables, data inconsistency may occur. Java programs rely on synchronized to synchronize threads, and when synchronized is used, it is important which object is locked. The lock acquired by synchronized is an object lock, rather than a piece of code or method as a lock. Therefore, that line first executes a method decorated with the synchronized keyword, which method holds the lock of the object that the method belongs to. Other threads can only wait, provided that multiple threads access the same object. If multiple threads access multiple objects, the JVM creates multiple object locks. Synchronized modifies ordinary methods to acquire the lock object this, while synchronized modifies static methods to acquire the bytecode of the current class

2.2 reentrant lock

The keyword synchronized has the function of reentrant, which means that with synchronized, a thread that has acquired an object lock can acquire the object lock again if it requests additional object locks.

Synchronized (class) blocks of code serve the same purpose as synchronized static methods

2.3 Automatic lock release

When code executed by a thread fails, the lock it holds is automatically released.

2.4 Synchronization does not have inheritance

In addition to synchronizing code blocks using syncrhonized(this), Java also supports “any object” as an “object lock” for synchronization. This “any object” large number is an argument to a member variable or method, using the format synchronized(not this object).

In the case of multiple threads holding an “object lock” on the same object, only one thread can execute the code in a synchronized(non-this object) block at a time. If you use a different object lock, the result of running is an asynchronous call, which runs interleaved.

2.6 String as object, because constant pool, the same string is the same object. Using an instance of a custom class as an object, the member variables of the class change, but the lock object does not change, because the memory address corresponding to the object instance does not change

2.7 a deadlock

It refers to a deadlock caused by multiple threads competing for resources during operation. When the threads are in this deadlock state, they cannot continue to run without external force.

package chap2;

public class Demo23 { public static void main(String[] args) throws InterruptedException { Demo23Thread t = new Demo23Thread(); t.setFlag(“a”);

    Thread t1 = new Thread(t);
    t1.start();
    Thread.sleep(10);

    t.setFlag("b");
    Thread t2 = new Thread(t);
    t2.start();
}
Copy the code

}

class Demo23Thread extends Thread{ private String flag; Private Object lock1 = new Object(); private Object lock2 = new Object();

public void setFlag(String flag){ this.flag = flag; } @Override public void run() { try { if ("a".equals(flag)) { synchronized (lock1) { System.out.println("flag=" + flag);  Thread.sleep(3000); Synchronized (lock2) {system.out.println (" lock1=>lock2 "); synchronized (lock2) {system.out.println (" lock1=>lock2 "); } } } else { synchronized (lock2){ System.out.println("flag=" + flag); Thread.sleep(3000); Synchronized (lock1){system.out.println (" lock2->lock1 "); synchronized (lock1){system.out.println (" lock2->lock1 "); } } } }catch (InterruptedException e){ e.printStackTrace(); }}Copy the code

}

2.8 Synchronize and volatile

Volatile is an easy implementation of thread synchronization, performs better than synchronized, and can only modify variables. Synchronized can modify methods and code blocks. With the update of JDK, the efficiency of synchronized has been greatly improved, and the usage of synchronized is still high in development

Multithreaded access to volatile will not block, whereas synhcronized will block

Volatile guarantees visibility but not atomicity, while synchronized guarantees atomicity and indirectly guarantees visibility because it synchronizes data in private and public memory.

Volatile addresses the visibility of variables across multiple threads, while synchronized addresses the synchronization of access to resources across multiple threads

In summary, volatile addresses the visibility and ordering of variables across multiple threads (preventing instruction reordering), while synchronized addresses the synchronization of access to resources across multiple threads

  1. Communication between threads

Threads are individual parts of a program, but these leobytes can become a whole if they are not processed. The communication between threads is to become one of the overall winning scheme, can be said to make the communication between threads, the interaction between threads will be more powerful, greatly improve the CPU reuse rate, but also enable programmers to each thread task in the process of processing effective control and supervision.