参考应用连接:https://www.jianshu.com/p/1f19835e05c0
1=============================(减少计数)
package com.atguigu.www.CountDownLatch;
import java.util.concurrent.CountDownLatch;
/**
*
* @Description:
* *让一些线程阻塞直到另一些线程完成一系列操作后才被唤醒。
*
*
* 解释:6个同学陆续离开教室后值班同学才可以关门。
*
* main主线程必须要等前面6个线程完成全部工作后,自己才能开干
*/
public class CountDownLatchDemo {//减少计数
public static void main(String[] args) throws InterruptedException {
CountDownLatch cd = new CountDownLatch(6);
for (int i = 1; i <=6; i++) {
new Thread(()->{
System.out.println(Thread.currentThread().getName()+"\t 号同学离开教室");
cd .countDown();//减少锁的数量,释放所有等待的线程,如果计数为零。
}, String.valueOf(i)).start();
}
cd.await();//使当前线程等待直到锁向下计数为零,除非线程 interrupted
System.out.println(Thread.currentThread().getName()+"\t 班长锁门离开");
}
}
2=============================( 循环栅栏)
package com.atguigu.www.CyclicBarrier;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
/**
*
* @Description: TODO(这里用一句话描述这个类的作用)
*
* CyclicBarrier
* 的字面意思是可循环(Cyclic)使用的屏障(Barrier)。它要做的事情是,
* 让一组线程到达一个屏障(也可以叫同步点)时被阻塞,
* 直到最后一个线程到达屏障时,屏障才会开门,所有
* 被屏障拦截的线程才会继续干活。
* 线程进入屏障通过CyclicBarrier的await()方法。
*
* 集齐7颗龙珠就可以召唤神龙
*/
public class CyclicBarrierDemo {//CyclicBarrier 循环栅栏
private static final int NUMBER = 7;
public static void main(String[] args) {
CyclicBarrier db = new CyclicBarrier(NUMBER,()->{
System.out.println("集齐7颗龙珠召唤神龙!!!");
});
for (int i = 1; i <=7; i++) {
new Thread(()->{
try {
System.out.println(Thread.currentThread().getName()+"\t 星龙珠被收集!");
db.await();
} catch (Exception e) {
e.printStackTrace();
}//等到所有的 parties援引 await这个屏障。
}, String.valueOf(i)).start();
}
}
}
3=============================(Callable)
package com.atguigu.www.JUC_Callable;
import java.util.concurrent.Callable;
public class MyThread implements Callable<Integer>{//callable接口
@Override
public Integer call() throws Exception {
Thread.sleep(4000);
System.out.println(Thread.currentThread().getName()+" *****come in call");
return 200;
}
}
package com.atguigu.www.JUC_Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class CallableDemo {
public static void main(String[] args) throws InterruptedException, ExecutionException{
FutureTask<Integer> ftA = new FutureTask<>(new MyThread());
new Thread(ftA, "AA").start();
FutureTask<Integer> ftB = new FutureTask<>(new MyThread());
new Thread(ftB, "BB").start();
System.out.println(Thread.currentThread().getName()+"------main");
int resultA = ftA.get();//等待,如果需要计算完成,然后检索其结果。
System.out.println("**********result: "+resultA);
int resultB = ftB.get();//等待,如果需要计算完成,然后检索其结果。
System.out.println("**********result: "+resultB);
}
}
4=============================(Lock)
package com.atguigu.www.lock;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ShareData {
private int number = 1 ; //1:A 2:B 3:C
Lock lock = new ReentrantLock();//lock接口
Condition cd1 = lock.newCondition();
Condition cd2 = lock.newCondition();
Condition cd3 = lock.newCondition();
public void printA(int totalLoopNumber) {
//上锁
lock.lock();
try {
while(number!=1) {
try {
cd1.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (int i = 1; i <=5; i++) {
System.out.println(Thread.currentThread().getName()+"第"+totalLoopNumber+"轮"+i);
}
number = 2 ;
cd2.signal();
} finally {
//关锁
lock.unlock();
}
}
public void printB(int totalLoopNumber) {
//上锁
lock.lock();
try {
while(number!=2) {
try {
cd2.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (int i = 1; i <=10; i++) {
System.out.println(Thread.currentThread().getName()+"第"+totalLoopNumber+"轮"+i);
}
number = 3 ;
cd3.signal();
} finally {
//关锁
lock.unlock();
}
}
public void printC(int totalLoopNumber) {
//上锁
lock.lock();
try {
while(number!=3) {
try {
cd3.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (int i = 1; i <=15; i++) {
System.out.println(Thread.currentThread().getName()+"第"+totalLoopNumber+"轮"+i);
}
number = 1 ;
cd1.signal();
} finally {
//关锁
lock.unlock();
}
}
}
package com.atguigu.www.lock;
/**
*
* @Description:
* 多线程之间按顺序调用,实现A->B->C
* 三个线程启动,要求如下:
*
* AA打印5次,BB打印10次,CC打印15次
* 接着
* AA打印5次,BB打印10次,CC打印15次
* ......来10轮
*
*/
public class ThreadOrderAccess {
public static void main(String[] args) {
ShareData shareData = new ShareData();
new Thread(()->{
for (int i = 1; i <= 10; i++) {
//打印5次
shareData.printA(i);
}
}, "A").start();
new Thread(()->{
for (int i = 1; i <= 10; i++) {
//打印10次
shareData.printB(i);
}
}, "B").start();
new Thread(()->{
for (int i = 1; i <= 10; i++) {
//打印15次
shareData.printC(i);
}
}, "C").start();
}
}
5=============================(ReadWriteLock)
package com.atguigu.www.ReentrantReadWriteLock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class MyQueue {
private Object obj;
ReadWriteLock rwLock = new ReentrantReadWriteLock();//读写锁
public void readObj() {
rwLock.readLock().lock();
try {
System.out.println(Thread.currentThread().getName()+"读出的内容是:"+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()+"写的内容是:"+obj);
} catch (Exception e) {
e.printStackTrace();
} finally {
//解锁
rwLock.writeLock().unlock();
}
}
}
package com.atguigu.www.ReentrantReadWriteLock;
/**
*
* @Description: 一个线程写入,100个线程读取
*
*/
public class ReadWriteLockDemo {
public static void main(String[] args) {
MyQueue mq = new MyQueue();
new Thread(()->{
mq.writeObj("Hello ReadWriteLock!");
}, "AA").start();
for (int i = 1; i <=100; i++) {
new Thread(()->{
mq.readObj();
}, String.valueOf(i)).start();
}
}
}
6=============================(Semaphore)
package com.atguigu.www.Semaphore;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
public class SemaphoreDemo {//信号灯
public static void main(String[] args){
Semaphore sp = new Semaphore(3);
for (int i =1; i <=6; i++) {
new Thread(()->{
try {
sp.acquire();
} catch (InterruptedException e1) {
e1.printStackTrace();
}//从这个信号获取许可证,阻塞直到有一个可用的线程,或是 interrupted。
System.out.println(Thread.currentThread().getName()+"\t 号车停到停车位");
//Thread.sleep(3000);//休息三秒
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}//休息三秒
System.out.println(Thread.currentThread().getName()+"\t 号车离开停车位");
sp.release();//发布许可证,返回到信号。
}, String.valueOf(i)).start();
}
}
}
7=============================(synchronized)
package com.atguigu.www.synchronized_demo;
public class ShareData {
private int number = 0 ;
//加
public synchronized void increment() throws InterruptedException {
while(number!=0) {
wait();
}
number++;
System.out.println(Thread.currentThread().getName()+"number="+number);
notifyAll();//清楚所有等待
}
//减
public synchronized void decrement() throws InterruptedException {
while(number!=1) {
wait();
}
number--;
System.out.println(Thread.currentThread().getName()+"number="+number);
notifyAll();//清楚所有等待
}
}
package com.atguigu.www.synchronized_demo;
/**
*
* @Description:
* 现在有两个线程,
* 可以操作初始值为零的一个变量,
* 实现一个线程对该变量加1,一个线程对该变量减1,
* 交替,来10轮。
*
* * 笔记:Java里面如何进行工程级别的多线程编写
* 1多线程编程模板(套路)-----上
* 1.1 线程操作资源类
* 1.2 高内聚 低耦合
* 2多线程编程模板(套路)-----下
* 2.1 判断
* 2.2 干活
* 2.3 通知
*/
public class NotifyWaitDemo {
public static void main(String[] args) {
ShareData shareData = new ShareData();
//加
new Thread(()->{
for (int i = 0; i < 10; i++) {
try {
shareData.increment();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
},"AA").start();
//减
new Thread(()->{
for (int i = 0; i < 10; i++) {
try {
shareData.decrement();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
};
}
},"BB").start();
//加
new Thread(()->{
for (int i = 0; i < 10; i++) {
try {
shareData.increment();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
},"CC").start();
//减
new Thread(()->{
for (int i = 0; i < 10; i++) {
try {
shareData.decrement();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
};
}
},"DD").start();
}
}