What is JUC?

Java.util.concurrent a utility class used in concurrent programming

Process/thread retrospectives

What is a process/thread?

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. 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.

 

Process/thread example

Using QQ, there must be A qq.exe process, I can use QQ to chat with A text, video chat with B, send files to C, send A language to D, QQ supports the search of input information. When I was a senior, I wrote a paper in Word, played music with QQ music, and chatted with QQ at the same time. If Word is not saved, power off, power off, and then open Word can restore the previously unsaved documents, Word will also check your spelling, two threads: disaster recovery backup, grammar check

The Lock interface

Review the Synchronized

Multithreaded programming template

Thread manipulates resource classes

2, high cohesion and low coupling

Implementation steps

1. Create a resource class

2, resource class create synchronization method, synchronization code block

Lock

What is Lock?

Lock implementations provide more extensive locking operations than can be obtained using synchronized methods and statements. They allow more flexible structuring, may have quite different properties, And may support multiple associated Condition objects. Lock implementations provide a wider range of locking operations and can be better than obtaining methods and declarations using synchronized. They allow for a more flexible structure, can have completely different features, and can support multiple related Condition objects.

The implementation of the Lock interface ReentrantLock can be reentrant locking

How to use it?

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

Thread creation

Inheriting Thread (cannot be written like this)

Public Class SaleTicket extends Thread Java is a single inheritance and provides valuable resourcesCopy the code

New Thread() (cannot be written like this)

Thread t1 = new Thread();
   t1.start();
Copy the code

Thread(Runnable target, String name)

 

There are three ways to implement threads

Create a new class that implements the Runnable interface

Class MyThread implements Runnable new Thread(new MyThread,...) This method will add new classes, there are newer and better methodsCopy the code

Anonymous inner class

new Thread(new Runnable() { @Override public void run() { } }, "your thread name").start(); Instead of creating a new class, you can create a new interfaceCopy the code

Lambda expressions

new Thread(() -> { }, "your thread name").start(); This way the code is more conciseCopy the code

The code examples

package com.atguigu.thread; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; Class Ticket // Example eld +method {private int number=30; Public synchronized void sale() {//2 synchronized(this) {} if(number > 0) { System.out.println(thread.currentThread ().getName()+" sell "+(number--)+"\t "); } }*/ // Lock implementations provide more extensive locking operations // than can be obtained using synchronized methods and statements. private Lock lock = new ReentrantLock(); //List list = new ArrayList() public void sale() { lock.lock(); Try {if(number > 0) {system.out.println (thread.currentThread ().getName()+" sell "+(number--)+"\t "); } } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); }}} /** ** @description: Public class SaleTicket {public static void main(String[] args)//main all program Ticket ticket = new Ticket(); //Thread(Runnable target, String name) Allocates a new Thread object. new Thread(() -> {for (int i = 1; i < 40; i++)ticket.sale(); }, "AA").start(); new Thread(() -> {for (int i = 1; i < 40; i++)ticket.sale(); }, "BB").start(); new Thread(() -> {for (int i = 1; i < 40; i++)ticket.sale(); }, "CC").start(); /* new Thread(new Runnable() { @Override public void run() { for (int i = 1; i <=40; i++) { ticket.sale(); } } }, "AA").start(); new Thread(new Runnable() { @Override public void run() { for (int i = 1; i <=40; i++) { ticket.sale(); } } }, "BB").start(); new Thread(new Runnable() { @Override public void run() { for (int i = 1; i <=40; i++) { ticket.sale(); } } }, "CC").start(); //1 class thread implements Runnable //2 class thread implements Runnable //3Copy the code

 

Java8 new features

Lambda expressions

Interfaces have only one method

Lambda expressions, if an interface has only one method, I can omit the method name Foo Foo = () -> {system.out.println ("****hello lambda"); };Copy the code

How to write: Copy the parentheses (), write the right arrow ->, drop the curly braces {… }

Functional interface

Lambda expression, it has to be a functional interface, it has to have only one method and if the interface has only one method Java defaults it to a functional interface. To use Lambda expressions properly, you need to comment the interface with @functionalInterface: Why can the Runnable interface use Lambda expressions?Copy the code

Can there be implementation methods in the interface?

The default method

Default int div(int x,int y) {return x/y; } how many methods can there be in the default interface?Copy the code

Static method implementation

Public static int sub(int x,int y){return x-y; public static int sub(int x,int y){return x-y; } how many can there be? Notice how static class methods are called. Can you call them in foo? To change to FooCopy the code

Code examples:

package com.atguigu.thread; @FunctionalInterface interface Foo{ // public void sayHello() ; // public void say886() ; public int add(int x,int y); default int div(int x,int y) { return x/y; } public static int sub(int x,int y) { return x-y; } } /** * * @Description: Lambda Express-----> Functional programming * 1 Copy the parentheses (parameter list), write the dead right arrow ->, {method implementation} * 2 There is only one public method @FunctionalInterface annotation enhancement * 3 Default method implementation * 4 Static method implementation */ public class LambdaDemo { public static void main(String[] args) { // Foo foo = new Foo() { // @Override // public void sayHello() { // System.out.println("Hello!!" ); // } // // @Override // public void say886() { // // TODO Auto-generated method stub // // } // }; // foo.sayHello(); // System.out.println("============"); // foo = ()->{System.out.println("Hello!! lambda !!" ); }; // foo.sayHello(); Foo foo = (x,y)->{ System.out.println("Hello!! lambda !!" ); return x+y; }; Int result = foo. The add (3, 5); System.out.println("******result="+result); System.out.println("******result div="+foo.div(10, 2)); System.out.println("******result sub="+Foo.sub(10, 2)); }}Copy the code

Callable interface

What is the Callable interface?

This is a functional interface and can therefore be used as an assignment object for lambda expressions or method references.

 

Compared with a runnable

Comparison of implementation methods

MyThread implements runnable {@override public void run() {}} MyThread implements runnable class MyThread2 implements Callable<Integer>{ @Override public Integer call() throws Exception { return 200; }} What is the difference between a Callable interface and a runnable interface? Answer :(1) whether there is a return value (2) whether an exception is thrown (3) the landing method is different, one is run, the other is callCopy the code

How does it work?

Is it possible to replace runnable directly?

Not feasible because: The thread class constructor has no Callable at all

 

It’s like getting to know someone I don’t know. I can get an intermediary to introduce me.

What is a middleman? Java polymorphism, a class can implement multiple interfaces!!

FutureTask

ft = new FutureTask

(new MyThread()); new Thread(ft, “AA”).start(); How do I get the return value after a successful run?

ft.get();

 

FutureTask

What is?

Future tasks, use it to do one thing, asynchronous call

The main method is like a rock sugar gourd, with each method strung together by Main.

But it doesn’t solve one problem: the normal call suspension blocking problem



Example:

(1) When the teacher is thirsty in class, it is not appropriate to buy water. The lecture thread continues, so I can ask the monitor to help me buy water.

I bought the water and put it on the table. I can get it when I need it.

(2) Four students, A is 1+20,B is 21+30,C is 31* to 40,D is 41+50.

FutureTask provides C with a single thread for calculation. I first summarize ABD, and then summarize C after C finishes calculation to get the final result

(3) College entrance examination: can do first, can’t do behind

Principle:

When you need to perform time-consuming operations on the main thread, but don't want to block the main thread, you can hand those jobs to the Future to be done in the background. When the main thread needs them in the Future, the Future object can be used to obtain the results of the calculation or execution status of the background job. Generally, FutureTask is used for time-consuming calculations. The main thread can obtain results after completing its own tasks. Retrieve the results only when the calculation is complete; Block the GET method if the calculation is not complete. Once the calculation is complete, it cannot be restarted or cancelled. The get method gets the result only when the calculation is complete, otherwise it blocks until the task is completed, and then returns the result or throws an exception. We only evaluate the get method once and put it at the endCopy the code

Code:

package com.atguigu.thread; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; class MyThread implements Callable<Integer> { @Override public Integer call() throws Exception { Thread.sleep(4000); System.out.println(Thread.currentThread().getName()+" *****come in call"); return 200; } } /** * * @Description: Public class CallableDemo {public static void main(String[] args) public static void main(String[] args)  throws InterruptedException, ExecutionException { FutureTask<Integer> ft = new FutureTask<Integer>(new MyThread()); new Thread(ft, "AA").start(); /*FutureTask<Integer> ft2 = new FutureTask<Integer>(new MyThread()); new Thread(ft2, "BB").start(); */ System.out.println(Thread.currentThread().getName()+"------main"); Integer result = ft.get(); //Integer result2 = ft2.get(); System.out.println("**********result: "+result); }} /** ** If you need to perform time-consuming operations on the main thread but don't want to block the main thread, you can hand them over to the Future object to be done in the background. When the main thread needs them in the Future, you can use the Future object to get the calculation results or execution status of the background job. Generally, FutureTask is used for time-consuming calculations. The main thread can obtain results after completing its own tasks. Retrieve the results only when the calculation is complete; Block the GET method if the calculation is not complete. Once the calculation is complete, it cannot be restarted or cancelled. The get method gets the result only when the calculation is complete, otherwise it blocks until the task is completed, and then returns the result or throws an exception. Only evaluate get once and put it at the end */Copy the code

Interthread communication

Interthread communication: 1. Producer + consumer. 2

Synchronized implementation

Code:

package com.atguigu.thread; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import org.omg.IOP.Codec; Class ShareDataOne// private int number = 0; Public synchronized void increment() throws InterruptedException {if(number! =0 ) { this.wait(); } //2 work ++number; System.out.println(Thread.currentThread().getName()+"\t"+number); / / 3 notice this. NotifyAll (); } public synchronized void decrement() throws InterruptedException {// 1 check if (number == 0) {this.wait(); } // 2 work --number; System.out.println(Thread.currentThread().getName() + "\t" + number); // 3 notify this.notifyall (); }} /** ** @description: * Now two threads, * can operate on a variable whose initial value is zero, * implement one thread to increment the variable, one thread to decrease the variable, * alternate, for 10 rounds. * @author xialei * * * Java inside how to write engineering level multithreading * 1 multithreading into templates (routines) ----- * 1.1 thread operation resource classes * 1.2 high cohesion low coupling * 2 multithreading into templates (routines) ----- below * 2.1 judgment * 2.2 work * 2.3 Public class NotifyWaitDemoOne {public static void main(String[] args) {ShareDataOne sd = new ShareDataOne(); new Thread(() -> { for (int i = 1; i < 10; i++) { try { sd.increment(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }, "A").start(); new Thread(() -> { for (int i = 1; i < 10; i++) { try { sd.decrement(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }, "B").start(); }} /* * * * 2 Multithreading into templates (routines) ----- down * 2.1 judgment * 2.2 work * 2.3 notification * 3 Prevent false wake up with while * * * */Copy the code

Let’s switch to four threads

Change to 4 threads will lead to error, false wake up reason: in Java multi-threaded judgment, can not use if, the program has an accident on the judgment, suddenly one day added thread into if, suddenly interrupted to hand over control, without verification, but directly went down, added twice, or even several timesCopy the code

Solutions:

Resolve false wake up: Look at the API, java.lang.object



Interrupts and false awakenings are possible, so use a loop where if is only judged once and while is woken up and pulled back again. If for a while

Code:

package com.atguigu.thread; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import org.omg.IOP.Codec; Private int number = 0; private int number = 0; Public synchronized void increment() throws InterruptedException { =0) { this.wait(); } // work ++number; System.out.println(Thread.currentThread().getName()+" \t "+number); / / notice this. NotifyAll ();; } public synchronized void decrement() throws InterruptedException {// Judge while(number! =1) { this.wait(); } // work --number; System.out.println(Thread.currentThread().getName()+" \t "+number); / / notice this. NotifyAll (); }} /** ** @description: * Now two threads, * can operate on a variable whose initial value is zero, * implement one thread to increment the variable, one thread to decrease the variable, * alternate, for 10 rounds. * * * Notes: Java inside how to write engineering level multithreading * 1 multithreading into templates (routines) ----- * 1.1 thread operation resource classes * 1.2 high cohesion low coupling * 2 multithreading into templates (routines) ----- below * 2.1 judgment * 2.2 work * 2.3 Public class NotifyWaitDemo {public static void main(String[] args) {ShareData sd = new ShareData(); new Thread(() -> { for (int i = 1; i <= 10; i++) { try { sd.increment(); } catch (InterruptedException e) { e.printStackTrace(); } } }, "A").start(); new Thread(() -> { for (int i = 1; i <= 10; i++) { try { sd.decrement(); } catch (InterruptedException e) { e.printStackTrace(); } } }, "B").start(); new Thread(() -> { for (int i = 1; i <= 10; i++) { try { sd.increment(); } catch (InterruptedException e) { e.printStackTrace(); } } }, "C").start(); new Thread(() -> { for (int i = 1; i <= 10; i++) { try { sd.decrement(); } catch (InterruptedException e) { e.printStackTrace(); } } }, "D").start(); }} /* * * * 2 Multithreading becomes template (routine) ----- under * 2.1 judgment * 2.2 work * 2.3 notification * 3 Prevent false wake up with while * * */Copy the code

Schematic diagram:

Java8 new implementation

For the implementation

Condition

Condition: Check the API, java.util.concurrent

 

class BoundedBuffer { final Lock lock = new ReentrantLock(); final Condition notFull = lock.newCondition(); final Condition notEmpty = lock.newCondition(); final Object[] items = new Object[100]; int putptr, takeptr, count; public void put(Object x) throws InterruptedException { lock.lock(); try { while (count == items.length) notFull.await(); items[putptr] = x; if (++putptr == items.length) putptr = 0; ++count; notEmpty.signal(); } finally { lock.unlock(); }}Copy the code

Code:

package com.atguigu.thread; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import org.omg.IOP.Codec; Private int number = 0; private int number = 0; Private Lock Lock = new ReentrantLock(); private Condition condition = lock.newCondition(); public void increment() throws InterruptedException { lock.lock(); Try {// judge while(number! =0) { condition.await(); } // work ++number; System.out.println(Thread.currentThread().getName()+" \t "+number); / / notice condition. SignalAll (); } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } } public void decrement() throws InterruptedException { lock.lock(); Try {// judge while(number! =1) { condition.await(); } // work --number; System.out.println(Thread.currentThread().getName()+" \t "+number); / / notice condition. SignalAll (); } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); }} /* Public synchronized void increment() throws InterruptedException { =0) { this.wait(); } // work ++number; System.out.println(Thread.currentThread().getName()+" \t "+number); / / notice this. NotifyAll ();; } public synchronized void decrement() throws InterruptedException {// Judge while(number! =1) { this.wait(); } // work --number; System.out.println(Thread.currentThread().getName()+" \t "+number); / / notice this. NotifyAll (); }*/} /** * @description: * Now two threads can operate on a variable with an initial value of zero, * one thread increments the variable by 1, and one thread decreases the variable by 1, * alternately, for 10 rounds. * @author xialei * * * Java inside how to write engineering level multithreading * 1 multithreading into templates (routines) ----- * 1.1 thread operation resource classes * 1.2 high cohesion low coupling * 2 multithreading into templates (routines) ----- below * 2.1 judgment * 2.2 work * 2.3 Public class NotifyWaitDemo {public static void main(String[] args) {ShareData sd = new ShareData(); new Thread(() -> { for (int i = 1; i <= 10; i++) { try { sd.increment(); } catch (InterruptedException e) { e.printStackTrace(); } } }, "A").start(); new Thread(() -> { for (int i = 1; i <= 10; i++) { try { sd.decrement(); } catch (InterruptedException e) { e.printStackTrace(); } } }, "B").start(); new Thread(() -> { for (int i = 1; i <= 10; i++) { try { sd.increment(); } catch (InterruptedException e) { e.printStackTrace(); } } }, "C").start(); new Thread(() -> { for (int i = 1; i <= 10; i++) { try { sd.decrement(); } catch (InterruptedException e) { e.printStackTrace(); } } }, "D").start(); }} /* * * * 2 Multithreading becomes template (routine) ----- under * 2.1 judgment * 2.2 work * 2.3 notification * 3 Prevent false wake up with while * * */Copy the code

Custom call communication between threads

Thread-call-resource class

Judge – do – inform

Condition 3, judge flag bit 4, output thread name + number of times + number of rounds 5, modify flag bit, notify the next code:

package com.atguigu.thread; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; class ShareResource { private int number = 1; //1:A 2:B 3:C private Lock lock = new ReentrantLock(); private Condition c1 = lock.newCondition(); private Condition c2 = lock.newCondition(); private Condition c3 = lock.newCondition(); public void print5(int totalLoopNumber) { lock.lock(); //1 check while(number! = 1) {//A is about to stop c1.await(); } //2 for (int I = 1; i <=5; i++) { System.out.println(Thread.currentThread().getName()+"\t"+i+"\t totalLoopNumber: "+totalLoopNumber); } //3 notify number = 2; c2.signal(); } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } } public void print10(int totalLoopNumber) { lock.lock(); //1 check while(number! = 2) {//A is about to stop c2.await(); } //2 for (int I = 1; i <=10; i++) { System.out.println(Thread.currentThread().getName()+"\t"+i+"\t totalLoopNumber: "+totalLoopNumber); } //3 notification number = 3; c3.signal(); } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } } public void print15(int totalLoopNumber) { lock.lock(); //1 check while(number! = 3) {//A is about to stop c3.await(); } //2 for (int I = 1; i <=15; i++) { System.out.println(Thread.currentThread().getName()+"\t"+i+"\t totalLoopNumber: "+totalLoopNumber); } //3 notify number = 1; c1.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 *...... @author xialei * */ public Class ThreadOrderAccess {public static void main(String[] args) {ShareResource sr = new ShareResource(); new Thread(() -> { for (int i = 1; i <=10; i++) { sr.print5(i); } }, "AA").start(); new Thread(() -> { for (int i = 1; i <=10; i++) { sr.print10(i); } }, "BB").start(); new Thread(() -> { for (int i = 1; i <=10; i++) { sr.print15(i); } }, "CC").start(); }}Copy the code

Multithreaded lock

8 Problems with locks

1 Standard access, print SMS first or email 2 Stop for 4 seconds in the SMS method, print SMS first or email 3 Ordinary Hello method, text first or Hello 4 Now there are two mobile phones, print SMS first or email 5 Two static synchronization methods, 1 mobile phone, Print text message or E-mail 6 two static synchronous method, 2 phone, print text message or E-mail 7 a static synchronization method, a common synchronization method, a phone, first printed text message or E-mail 8 1 static synchronization method, a common synchronization method, 2 phone, print a text message or email to run the answer: 1, short message 2, short message 3, Hello 4, short message 5, short message 6, short message 7, mail 8, mailCopy the code

Lock analysis:

(A) If there are multiple synchronized methods in an object, at any given moment A thread calls one of the synchronized methods, and all the other threads have to wait. In other words, at any given moment, The only thread that can access the synchronized method lock is the current object this. After this object is locked, no other thread can access the other synchronized methods of the current object. Synchronized is the basis for implementing synchronization: every object in Java can be used as a lock. Specific performance for the following three forms. For normal synchronous methods, the lock is the current instance object. For statically synchronized methods, the lock is the Class object of the current Class. For synchronized method blocks, locks are Synchonized parenthesized objects. When a thread attempts to access a synchronized code block, it must first acquire the lock and release the lock when it exits or throws an exception. That is, if a non-statically synchronized method of an instance acquires a lock, the other non-statically synchronized methods of the instance must wait for the method that acquires the lock to release the lock. However, the non-statically synchronized methods of other instances use a different lock than the non-statically synchronized methods of the instance. So non-statically synchronized methods can acquire their own locks without waiting for the instance object to have acquired them to release the lock. All statically synchronized methods use the same lock -- the class object itself. These two locks are two different objects, so there are no race conditions between statically synchronized methods and non-statically synchronized methods. But once a statically synchronized method acquires the lock, all other statically synchronized methods must wait for that method to release the lock before acquiring it, whether between statically synchronized methods of the same instance object or between statically synchronized methods of different instance objects, as long as they are of the same class!Copy the code

Code:

package com.atguigu.thread; import java.util.concurrent.TimeUnit; class Phone { public synchronized void sendSMS() throws Exception { System.out.println("------sendSMS"); } public synchronized void sendEmail() throws Exception { System.out.println("------sendEmail"); } public void getHello() { System.out.println("------getHello"); } } /** * * @Description: 8 Lock * @author xialei * 1 Standard access, print SMS first or email 2 Stop 4 seconds in the SMS method, print SMS first or email 3 New ordinary Hello method, is to text first or Hello 4 Now there are two mobile phones, print SMS first or email 5 two static synchronization methods, 1 cell phone, print SMS or email first 6 two static synchronization methods, 2 cell phones, print SMS or email first 7 1 static synchronization method,1 normal synchronization method,1 cell phone, print SMS or email first 8 1 static synchronization method,1 normal synchronization method, 2 cell phones, Print text message or E-mail * -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - * * / public class Lock_8 {public static void main (String [] args) throws Exception { Phone phone = new Phone(); Phone phone2 = new Phone(); new Thread(() -> { try { phone.sendSMS(); } catch (Exception e) { e.printStackTrace(); } }, "AA").start(); Thread.sleep(100); new Thread(() -> { try { phone.sendEmail(); //phone.getHello(); //phone2.sendEmail(); } catch (Exception e) { e.printStackTrace(); } }, "BB").start(); }}Copy the code

JUC powerful tutorial classes

ReentrantReadWriteLock read-write lock

package com.atguigu.thread; import java.util.concurrent.locks.ReentrantReadWriteLock; class MyQueue { private Object obj; private ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock(); public void readObj() { rwLock.readLock().lock(); try { System.out.println(Thread.currentThread().getName()+"\t"+obj); } catch (Exception e) { e.printStackTrace(); } finally { rwLock.readLock().unlock(); } } public void writeObj(Object obj) { rwLock.writeLock().lock(); try { this.obj = obj; System.out.println(Thread.currentThread().getName()+"writeThread:\t"+obj); } catch (Exception e) { e.printStackTrace(); } finally { rwLock.writeLock().unlock(); } } } /** * * @Description: * @author xialei * */ public class ReadWriteLockDemo {public static void main(String[] args) throws InterruptedException { MyQueue q = new MyQueue(); new Thread(() -> { q.writeObj("ClassName1221"); }, "AAAAA").start(); for (int i = 1; i <=100; i++) { new Thread(() -> { q.readObj(); },String.valueOf(i)).start(); }}}Copy the code

CountDownLatch reduces the count

Principle:

* CountDownLatch has two main methods that block when one or more threads call the await method. * Another thread calling the countDown method will decrement the counter by one (the thread calling the countDown method will not block), and when the counter value becomes zero, the thread blocked by the await method will wake up and continue execution.

Code:

package com.atguigu.thread; import java.util.concurrent.CountDownLatch; /** ** @description: ** Lets some threads block until another thread completes a sequence of operations. * * CountDownLatch has two main methods that block when one or more threads call the await method. * Another thread calling the countDown method will decrement the counter by one (the thread calling the countDown method will not block), and when the counter value becomes zero, the thread blocked by the await method will wake up and continue execution. * * Explanation: students on duty can not close the door until 6 students have left the classroom. * * The main thread must wait for the first 6 threads to complete their work, */ public class CountDownLatchDemo {public static void main(String[] args) throws InterruptedException { CountDownLatch countDownLatch = new CountDownLatch(6); for (int i = 1; i <=6; {new Thread(() -> {system.out.println (thread.currentThread ().getName()+"\t ")); countDownLatch.countDown(); }, String.valueOf(i)).start(); } countDownLatch.await(); System.out.println(thread.currentThread ().getName()+"\t****** "); }}Copy the code

CyclicBarrier

Principle:

CyclicBarrier * literally means a Barrier that can be used Cyclic. What it does is * let a group of threads block when they reach a barrier (also known as a synchronization point), * the barrier will not open until the last thread reaches the barrier, and all threads blocked by the barrier will continue to work. * Threads enter barriers through the await() method of CyclicBarrier.Copy the code

Code:

package com.atguigu.thread; import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; /** ** @description: TODO(here is a one-sentence Description of what this class does) ** CyclicBarrier * literally means CyclicBarrier. What it does is * let a group of threads block when they reach a barrier (also known as a synchronization point), * the barrier will not open until the last thread reaches the barrier, and all threads blocked by the barrier will continue to work. * Threads enter barriers through the await() method of CyclicBarrier. CyclicBarrierDemo public class CyclicBarrierDemo {private static final int NUMBER = 7; CyclicBarrierDemo public class CyclicBarrierDemo {private static final int NUMBER = 7; public static void main(String[] args) { //CyclicBarrier(int parties, Runnable barrierAction) CyclicBarrier cyclicBarrier = new CyclicBarrier(NUMBER, ()->{system.out.println ("***** collect 7 dragon ball can call the dragon "); }); for (int i = 1; i <= 7; I++) {new Thread(() -> {try {system.out.println (thread.currentthread ().getname ()+"\t "); cyclicBarrier.await(); } catch (InterruptedException | BrokenBarrierException e) { // TODO Auto-generated catch block e.printStackTrace(); } }, String.valueOf(i)).start(); }}}Copy the code

Semaphore signals

Principle:

On semaphores we define two operations: * acquire When a thread calls acquire, it either acquires the semaphore successfully (the semaphore minus 1), or it waits until a thread releases the semaphore, or it times out. * Release actually increments the semaphore value by one and wakes up the waiting thread. * Semaphores are mainly used for two purposes, one is for mutually exclusive use of multiple shared resources and the other is for control of the number of concurrent threads.

Code:

package com.atguigu.thread; import java.util.Random; import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; /** * * @Description: TODO * @author xialei * * On semaphores we define two operations: When a thread calls acquire, it either acquires a semaphore successfully (minus 1), or waits until a thread releases a semaphore, or times out. * Release actually increments the semaphore value by one and wakes up the waiting thread. * * Semaphores are mainly used for two purposes, one is for mutually exclusive use of multiple shared resources and the other is for control of the number of concurrent threads. */ public class SemaphoreDemo { public static void main(String[] args) { Semaphore semaphore = new Semaphore(3); For (int I = 1; i <=6; New Thread(() -> {try {semaphore.acquire(); System.out.println(thread.currentThread ().getName()+"\t "); TimeUnit.SECONDS.sleep(new Random().nextInt(5)); System. Out. Println (Thread. CurrentThread (). The getName () + "\ t -- -- -- -- -- -- -- leave"); } catch (InterruptedException e) { e.printStackTrace(); }finally { semaphore.release(); } }, String.valueOf(i)).start(); }}}Copy the code