What is JUC
1. Juc (java.util.concurrent)
Java.util.concurrent is a utility class used in concurrent programming in java.util.concurrent, where JDK1.5 started.
2. Process and thread review
Process: A process is a running activity of a program with some independent function about a set of data. It is the basic unit of dynamic execution of operating system. In traditional operating system, process is both the basic unit of allocation and the basic unit of execution. (Simply understood as running programs on the computer, such as 360 anti-virus software, QQ Music, Chrome browser, etc.)
Thread: Usually a process can contain several threads, of course, a process has at least one thread, otherwise there is no point in existence. Thread can take advantage of the process has the resources, the introduction of the thread of the operating system, usually the process as the basic unit of the allocation of resources, the thread as the basic unit of the independent running and scheduling, because the thread process than smaller, basically does not have the system resources, so the scheduling of it pays expenses will be much smaller, It can improve the degree of concurrent execution between multiple programs more efficiently. 360 anti-virus software can clean up garbage and scan for viruses. Garbage cleaning can be viewed as a thread working, virus scanning as a thread working.)
3. Thread status
Thread.State
public enum State { /** * Thread state for a thread which has not yet started. */ NEW, Thread state for a runnable Thread. A Thread in the runnable * state is executing in the Java virtual machine but it may * be waiting for other resources from the operating system * such as processor. */ RUNNABLE, ** * Thread state for a Thread blocked waiting for a monitor lock. * A Thread in the blocked state is waiting for a monitor lock * to enter a synchronized block/method or * reenter a synchronized block/method after calling * {@link Object#wait() Object.wait}. */ BLOCKED, ** * Thread state for a waiting Thread. * A Thread is in the waiting state due to calling one of the * following methods: * <ul> * <li>{@link Object#wait() Object.wait} with no timeout</li> * <li>{@link #join() Thread.join} with no timeout</li> * <li>{@link LockSupport#park() LockSupport.park}</li> * </ul> * * <p>A thread in the waiting state is waiting for another thread to * perform a particular action. * * For example, a thread that has called <tt>Object.wait()</tt> * on an object is waiting for another thread to call * <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on * that object. A thread that has called <tt>Thread.join()</tt> * is waiting for a specified thread to terminate. */ WAITING, /** * specified Thread state for a waiting Thread with a specified waiting time. * a Thread is in the specified waiting time state due to calling one of * the following methods with a specified positive waiting time: * <ul> * <li>{@link #sleep Thread.sleep}</li> * <li>{@link Object#wait(long) Object.wait} with timeout</li> * <li>{@link #join(long) Thread.join} with timeout</li> * <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li> * <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li> * </ul> */ TIMED_WAITING, /** * Thread state for a terminated Thread. * The Thread has completed execution. / / end}Copy the code
4. What’s the difference between ‘wait’ and ‘sleep’
Wait: To release the lock and go to sleep
To sleep: to wait without releasing the lock
5. The difference between concurrency and parallelism
Concurrency: Multiple threads are accessing the same resource at the same time. Multiple threads operate on the same point. For example: Spring Festival rush tickets, e-commerce seconds kill
Parallelism: multiple tasks are executed together and then summarized. For example: instant noodles, you can tear the package of instant noodles and seasoning package, while boiling water
6. Multithreading skills
【 Multithreaded programming enterprise routine + template 】
Thread –> action (exposed calling method) –> resource class
2. Lock interface
1. What is Lock
The Lock implementation provides a wider range of locking operations than can be obtained using synchronized methods and statements. They allow for more flexible structuring, may have completely different attributes, and can support multiple related objects, conditions.
2. Lock interface implementation
ReentrantLock ReentrantLock
class X {
private final ReentrantLock lock = new ReentrantLock();
// ...
public void m() {
lock.lock(); // block until condition holds
try {
// ... method body
} finally {
lock.unlock()
}
}
}
Copy the code
- The difference between synchronized and Lock
1. Synchronized is a built-in Java keyword. On the JVM level, Lock is a Java class.
2. Synchronized cannot determine whether the Lock is obtained. Lock can determine whether the Lock is obtained.
3. Synchronized automatically releases the lock. The Lock must be released manually in finally (unlock()). Otherwise, the thread is likely to deadlock.
4. Two threads 1 and 2 that use the synchronized keyword, if the current thread 1 acquires the lock, thread 2 waits. If thread 1 is blocked, thread 2 will wait forever, while Lock does not necessarily wait. If an attempt to acquire the Lock fails, the thread can terminate without waiting forever.
5. Synchronized locks are reentrant, uninterruptible, and non-fair, while synchronized locks are reentrant, judge, and fair.
6.Lock Lock is suitable for a large number of synchronized code synchronization problems, synchronized Lock is suitable for a small number of code synchronization problems.
3. Ticket selling cases
(1) Use synchronized scheme
/** * Class Ticket{private int number = 30; Public synchronized void saleTicket(){if(number > 0){system.out.println (thread.currentThread ().getName()) \t: "+ (number-) + "\t:" + (number-) + "\t: "+ number); }}} /** * title: Three conductors sell 30 tickets ** Under the premise of high cohesion and low coupling, Thread operation (exposed invocation method) Resource class */ public class SaleTicket {public static void main(String[] args) {// Resource class Ticket Ticket = new Ticket(); New Thread(new Runnable() {@override public void run() {for (int I = 0; i <=40; i++) { ticket.saleTicket(); } } }, "A").start(); New Thread(new Runnable() {@override public void run() {for (int I = 0; i <= 40; i++) { ticket.saleTicket(); } } }, "B").start(); New Thread(new Runnable() {@override public void run() {for (int I = 0; i <=40; i++) { ticket.saleTicket(); } } }, "C").start(); }Copy the code
(2) Use juC lock lock scheme
/** * class TicketLock{private int number = 30; Lock lock = new ReentrantLock(); Public void saleTicket(){try {lock.lock(); public void saleTicket(){try {lock.lock(); Println (thread.currentThread ().getName() + "\t ":" + (number--) + "\t ":" + number); } finally { lock.unlock(); // Release the lock}}} /** * title: Three ticket sellers sell 30 tickets ** ** Under the premise of high cohesion and low coupling, Resource class */ public class SaleTicket {public static void main(String[] args) { / * * * * * * * * use juc lock lock mode in the * * * * * * * * / Ticket Ticket = new Ticket (); new Thread(() -> {for (int i = 0; i <= 40; i++) ticket.saleTicket(); }, "A").start(); new Thread(() -> {for (int i = 0; i <= 40; i++) ticket.saleTicket(); }, "B").start(); new Thread(() -> {for (int i = 0; i <= 40; i++) ticket.saleTicket(); }, "C").start(); }Copy the code
Execution Result:
3. Communication between threads
【 Multithreaded programming enterprise routine + template 】
1. Judge 2. Work 3
【 False wake up between multiple threads 】
Instead of using if, use while
1. Producer + consumer
Synchronizd, wait(), notifyAll()
/** * class AdditionAndSubtraction{private int number = 0; Public synchronized void increment() throws InterruptedException { = 0){ this.wait(); } // number++; System.out.println(Thread.currentThread().getName() + "\t" + number); / / notice this. NotifyAll (); } // Number minus 1 public synchronized void decrement() throws InterruptedException {// Check while(number == 0){this.wait(); } // work number--; System.out.println(Thread.currentThread().getName() + "\t" + number); / / notice this. NotifyAll (); }} /** * Title: Now two threads can operate on a variable with an initial value of zero, * implement one thread to increment the variable, one thread to the variable -1, * implement alternate, for 10 rounds, the variable initial value is 0. * 1. With high cohesion and low coupling, threads operate on resource classes * 2. Judge/do/notify * 3. Prevent false wake up (while, not if) Multithreaded programming routines + while judging + juc * / public class ProducersAndConsumersTest {public static void main (String [] args) { AdditionAndSubtraction additionAndSubtraction = new AdditionAndSubtraction(); new Thread(new Runnable() { @Override public void run() { for (int i = 0; i < 10; i++) { try { additionAndSubtraction.increment(); } catch (InterruptedException e) { e.printStackTrace(); } } } }, "A").start(); new Thread(new Runnable() { @Override public void run() { for (int i = 0; i < 10; i++) { try { additionAndSubtraction.decrement(); } catch (InterruptedException e) { e.printStackTrace(); } } } }, "B").start(); new Thread(new Runnable() { @Override public void run() { for (int i = 0; i < 10; i++) { try { additionAndSubtraction.increment(); } catch (InterruptedException e) { e.printStackTrace(); } } } }, "C").start(); new Thread(new Runnable() { @Override public void run() { for (int i = 0; i < 10; i++) { try { additionAndSubtraction.decrement(); } catch (InterruptedException e) { e.printStackTrace(); } } } }, "D").start(); }}Copy the code
Execution Result:
(2) the JUC way
class AdditionAndSubtraction2{ private int number = 0; private Lock lock = new ReentrantLock(); private Condition condition = lock.newCondition(); public void increment() throws InterruptedException { try { lock.lock(); // while (number! = 0){ condition.await(); } //2, number++; System.out.println(Thread.currentThread().getName() + "\t" +number); Condition. SignalAll (); } finally { lock.unlock(); } } public void decrement() throws InterruptedException { try { lock.lock(); While (number == 0){condition.await(); } //2; System.out.println(Thread.currentThread().getName() + "\t" + number); Condition. SignalAll (); } finally { lock.unlock(); }}} /** * Title: Now two threads can operate on a variable with the initial value of zero, * implement one thread to the variable increment 1, one thread to the variable -1, * implement alternate, for 10 rounds, the variable initial value 0. * 1. With high cohesion and low coupling, threads operate on resource classes * 2. Judge/do/notify * 3. Prevent false wake up (while, not if) * 4. Multithreaded programming routines + while judging + juc * / public class ProducersAndConsumersTest {public static void main (String [] args) { AdditionAndSubtraction2 additionAndSubtraction2 = new AdditionAndSubtraction2(); new Thread(() -> { for (int i = 0; i < 10; i++) { try { additionAndSubtraction2.increment(); } catch (InterruptedException e) { e.printStackTrace(); } } }, "A").start(); new Thread(() -> { for (int i = 0; i < 10; i++) { try { additionAndSubtraction2.decrement(); } catch (InterruptedException e) { e.printStackTrace(); } } }, "B").start(); new Thread(() -> { for (int i = 0; i < 10; i++) { try { additionAndSubtraction2.increment(); } catch (InterruptedException e) { e.printStackTrace(); } } }, "C").start(); new Thread(() -> { for (int i = 0; i < 10; i++) { try { additionAndSubtraction2.decrement(); } catch (InterruptedException e) { e.printStackTrace(); } } }, "D").start(); }}Copy the code
Execution Result:
4. Customized call communication between threads
package com.example.jucdemo.test; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; class ShareResource{ private int number = 1; //A:1,B:2,C:3,D:4 private Lock lock = new ReentrantLock(); private Condition condition1 = lock.newCondition(); private Condition condition2 = lock.newCondition(); private Condition condition3 = lock.newCondition(); public void print5(){ try { lock.lock(); //1, while (number! = 1){ condition1.await(); } for (int I = 0; i < 5; i++) { System.out.println(Thread.currentThread().getName() + "\t" + i); } //3, notify number = 2; condition2.signal(); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } } public void print10(){ try { lock.lock(); //1, while (number! = 2){ condition2.await(); } for (int I = 0; i < 10; i++) { System.out.println(Thread.currentThread().getName() + "\t" + i); } //3; condition3.signal(); }catch (Exception e) { e.printStackTrace(); }finally { lock.unlock(); } } public void printd15(){ try { lock.lock(); //1, while(number! = 3){ condition3.await(); } for (int I = 0; i < 10; i++) { System.out.println(Thread.currentThread().getName() + "\t" + i); } //3, notify number = 1; condition1.signal(); }catch (Exception e) { e.printStackTrace(); }finally { lock.unlock(); } } } /** * * @Description: * Multiple threads are called in order to achieve A->B->C * three threads start, the requirements are as follows: * * AA print 5 times, BB print 10 times, CC print 15 times * then * AA print 5 times, BB print 10 times, CC print 15 times *...... * */ public class ThreadOrderAccess {public static void main(String[] args) {ShareResource = new ShareResource(); New Thread(() -> {for (int I = 0; i < 10; i++) { shareResource.print5(); } }, "AA").start(); new Thread(() -> { for (int i = 0; i < 10; i++) { shareResource.print10(); } }, "BB").start(); new Thread(() -> { for (int i = 0; i < 10; i++) { shareResource.printd15(); } }, "CC").start(); }}Copy the code
Execution Result:
summary
Life first article dedicated to the nuggets, record their own study notes and life miscellanies