package com.juc;
public class SynchronizedTest {
public static void main(String[] args) {
Ticker ticker = new Ticker();
new Thread(()->{
for (int i = 0; i < 50; i++) {
ticker.sale();
}
},"A").start();
new Thread(()->{
for (int i = 0; i < 50; i++) {
ticker.sale();
}
},"B").start();
new Thread(()->{
for (int i = 0; i < 50; i++) {
ticker.sale();
}
},"C").start();
}
}
class Ticker{
int num = 50;
public synchronized void sale(){
if(num>0){
System.out.println(Thread.currentThread().getName()+"卖出了第"+(num--)+"票");
}
}
}
package com.juc;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class LockTest{
public static void main(String[] args) {
Ticker1 ticker = new Ticker1();
new Thread(()->{
for (int i = 0; i < 50; i++) {
ticker.sale();
}
},"A").start();
new Thread(()->{
for (int i = 0; i < 50; i++) {
ticker.sale();
}
},"B").start();
new Thread(()->{
for (int i = 0; i < 50; i++) {
ticker.sale();
}
},"C").start();
}
}
class Ticker1{
int num = 50;
Lock lock = new ReentrantLock();
public synchronized void sale(){
lock.lock();
try {
if(num>0){
System.out.println(Thread.currentThread().getName()+"卖出了第"+(num--)+"票");
}
}finally {
lock.unlock();
}
}
}
package com.juc.pc;
public class PcDemo01 {
public static void main(String[] args) {
Data data = new Data();
new Thread(()->{
for (int i = 0; i < 10; i++) {
data.increment();
}
},"A").start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
data.decrement();
}
},"B").start();
}
}
class Data {
int num = 0;
public synchronized void increment(){
if(num!=0){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
num ++;
System.out.println(num);
this.notifyAll();
}
public synchronized void decrement(){
if(num==0){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
num --;
System.out.println(num);
this.notifyAll();
}
}
package com.juc.pc;
public class PcDemo01 {
public static void main(String[] args) {
Data data = new Data();
new Thread(()->{
for (int i = 0; i < 10; i++) {
data.increment();
}
},"A").start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
data.decrement();
}
},"B").start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
data.increment();
}
},"C").start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
data.decrement();
}
},"D").start();
}
}
class Data {
int num = 0;
public synchronized void increment(){
while(num!=0){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
num ++;
System.out.println(Thread.currentThread().getName()+"=>"+num);
this.notifyAll();
}
public synchronized void decrement(){
while(num==0){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
num --;
System.out.println(Thread.currentThread().getName()+"=>"+num);
this.notifyAll();
}
}
package com.juc.pc;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class PcLockDemo01{
public static void main(String[] args) {
Data1 data = new Data1();
new Thread(()->{
for (int i = 0; i < 10; i++) {
data.increment();
}
},"A").start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
data.decrement();
}
},"B").start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
data.increment();
}
},"C").start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
data.decrement();
}
},"D").start();
}
}
class Data1 {
int num = 0;
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
public void increment(){
lock.lock();
try {
while(num!=0){
try {
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
num ++;
System.out.println(Thread.currentThread().getName()+"=>"+num);
condition.signalAll();
}finally {
lock.unlock();
}
}
public void decrement(){
lock.lock();
try {
while(num==0){
try {
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
num --;
System.out.println(Thread.currentThread().getName()+"=>"+num);
condition.signalAll();
}finally {
lock.unlock();
}
}
}
package com.juc.pc;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
//A-》B-》c-》A
public class ConditionHxDemo {
public static void main(String[] args) {
Data3 data3 = new Data3();
new Thread(()->{
for (int i = 0; i < 10; i++) data3.printA();
},"A").start();
new Thread(()->{
for (int i = 0; i < 10; i++) data3.printB();
},"B").start();
new Thread(()->{
for (int i = 0; i < 10; i++) data3.printC();
},"C").start();
}
}
class Data3{
private Lock lock = new ReentrantLock();
private Condition condition1 = lock.newCondition();
private Condition condition2 = lock.newCondition();
private Condition condition3 = lock.newCondition();
private int num = 1;
public void printA(){
lock.lock();
try {
while(1!=num){
try {
condition1.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+"====>AAAA");
num = 2;
condition2.signal();
}finally {
lock.unlock();
}
}
public void printB(){
lock.lock();
try {
while(2!=num){
try {
condition2.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+"====>BBBB");
num = 3;
condition3.signal();
}finally {
lock.unlock();
}
}
public void printC(){
lock.lock();
try {
while(3!=num){
try {
condition3.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+"====>CCCC");
num = 1;
condition1.signal();
}finally {
lock.unlock();
}
}
}
8锁
package com.juc.bLock;
import java.util.concurrent.TimeUnit;
/**
* 1.标准情况下先发短信还是打电话?发短信
* 因为锁的存在,
* synchronized锁的对象是方法的调用者
* 两个方法用的是同一个锁
* 所以谁先拿到锁谁先执行
*/
public class BLock01 {
public static void main(String[] args) throws InterruptedException {
Phone phone = new Phone();
new Thread(()->{
phone.sendSms();
}).start();
TimeUnit.SECONDS.sleep(1);
new Thread(()->{
phone.call();
}).start();
}
}
class Phone{
public synchronized void sendSms(){
System.out.println("发短信");
}
public synchronized void call(){
System.out.println("打电话");
}
}
package com.juc.bLock;
import java.util.concurrent.TimeUnit;
/**
* 2.发短信延迟4秒,先发短信还是先打电话? 发短信
*
*/
public class BLock02 {
public static void main(String[] args) throws InterruptedException {
Phone1 phone = new Phone1();
new Thread(()->{
phone.sendSms();
}).start();
TimeUnit.SECONDS.sleep(1);
new Thread(()->{
phone.call();
}).start();
}
}
class Phone1{
public synchronized void sendSms(){
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("发短信");
}
public synchronized void call(){
System.out.println("打电话");
}
}
package com.juc.bLock;
import java.util.concurrent.TimeUnit;
/**
* 3.增加一个普通方法后先执行发短信还是hello? hello
* hello方法没有加锁,所以不受锁的印象
*/
public class BLock03 {
public static void main(String[] args) throws InterruptedException {
Phone2 phone = new Phone2();
new Thread(()->{
phone.sendSms();
}).start();
TimeUnit.SECONDS.sleep(1);
new Thread(()->{
phone.hello();
}).start();
}
}
class Phone2{
public synchronized void sendSms(){
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("发短信");
}
public synchronized void call(){
System.out.println("打电话");
}
public void hello(){
System.out.println("hello");
}
}
package com.juc.bLock;
import java.util.concurrent.TimeUnit;
/**
* 4、两个对象两个同步方法,先执行发短信还是先执行发短信? 打电话
* synchronized锁的对象是方法的调用者
* 两个不同的对象有两把锁
*/
public class BLock04 {
public static void main(String[] args) throws InterruptedException {
Phone3 phone1 = new Phone3();
Phone3 phone2 = new Phone3();
new Thread(()->{
phone1.sendSms();
}).start();
TimeUnit.SECONDS.sleep(1);
new Thread(()->{
phone2.call();
}).start();
}
}
class Phone3{
public synchronized void sendSms(){
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("发短信");
}
public synchronized void call(){
System.out.println("打电话");
}
}
package com.juc.bLock;
import java.util.concurrent.TimeUnit;
/**
* 5.先发短信还是先打电话 发短信
* static静态方法,类一下加载就有了是一个class模板,Phone4只有唯一一个class对象(反射)
* synchronized锁的是class对象
*/
public class BLock05 {
public static void main(String[] args) throws InterruptedException {
Phone4 phone = new Phone4();
new Thread(()->{
phone.sendSms();
}).start();
TimeUnit.SECONDS.sleep(1);
new Thread(()->{
phone.call();
}).start();
}
}
class Phone4{
public static synchronized void sendSms(){
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("发短信");
}
public static synchronized void call(){
System.out.println("打电话");
}
}
package com.juc.bLock;
import java.util.concurrent.TimeUnit;
/**
* 6.先发短信还是先打电话? 发短信
* static静态方法,类一下加载就有了是一个class模板,Phone5只有唯一一个class对象(反射)
* synchronized锁的是class对象
*/
public class BLock06 {
public static void main(String[] args) throws InterruptedException {
Phone5 phone1 = new Phone5();
Phone5 phone2 = new Phone5();
new Thread(()->{
phone1.sendSms();
}).start();
TimeUnit.SECONDS.sleep(1);
new Thread(()->{
phone2.call();
}).start();
}
}
class Phone5{
public static synchronized void sendSms(){
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("发短信");
}
public static synchronized void call(){
System.out.println("打电话");
}
}
package com.juc.bLock;
import java.util.concurrent.TimeUnit;
/**
* 7、先发短信还是先打电话? 打电话
* 两把锁,static一个锁的是class模板, 一个是锁的事class对象
*/
public class BLock07 {
public static void main(String[] args) throws InterruptedException {
Phone6 phone = new Phone6();
new Thread(()->{
phone.sendSms();
}).start();
TimeUnit.SECONDS.sleep(1);
new Thread(()->{
phone.call();
}).start();
}
}
class Phone6{
public static synchronized void sendSms(){
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("发短信");
}
public synchronized void call(){
System.out.println("打电话");
}
}
package com.juc.bLock;
import java.util.concurrent.TimeUnit;
/**
* 先打电话还是先发短信? 打电话
*/
public class BLock08 {
public static void main(String[] args) throws InterruptedException {
Phone7 phone1 = new Phone7();
Phone7 phone2 = new Phone7();
new Thread(()->{
phone1.sendSms();
}).start();
TimeUnit.SECONDS.sleep(1);
new Thread(()->{
phone2.call();
}).start();
}
}
class Phone7{
public static synchronized void sendSms(){
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("发短信");
}
public synchronized void call(){
System.out.println("打电话");
}
}
package com.juc.collection;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* java.util.ConcurrentModificationException 并发修改异常
* 并发下ArrayList不安全
*
* 解决方案:
* 1、List<String> list = new Vector<String>(); Vector是安全的
* 2、Collections.synchronizedList()
* 3、juc包下 new CopyOnWriteArrayList<>()
*
*
* CopyOnWrite:写入时复制,cow 计算机程序设计领域的一种优化
* 多个线程调用的时候,List,读取的时候内容是固定的,写入(覆盖)
* 在写入的时候避免覆盖造成数据问题,所以先复制一份,之后再覆盖
* 读写分离
* CopyOnWriteArrayList比Vector好在哪里? CopyOnWriteArrayList用的lock锁,Vector用的是synchronized锁
*/
public class ListTest {
public static void main(String[] args) {
List<String> list = new CopyOnWriteArrayList<>();
for (int i = 0; i < 10; i++) {
new Thread(()->{
list.add(UUID.randomUUID().toString().substring(0,5));
System.out.println(list);
},String.valueOf(i)).start();
}
}
}
package com.juc.collection;
import java.util.*;
import java.util.concurrent.CopyOnWriteArraySet;
/**
* java.util.ConcurrentModificationException
* 解决方法:
* 1、Collections.synchronizedSet(new HashSet<String>())
* 2、new CopyOnWriteArraySet<>()
*/
public class SetTest {
public static void main(String[] args) {
// Set<String> set = new HashSet<String>();
// Set<String> set = Collections.synchronizedSet(new HashSet<String>());
Set<String> set = new CopyOnWriteArraySet<>();
for (int i = 0; i < 1000; i++) {
new Thread(()->{
set.add(UUID.randomUUID().toString().substring(0,5));
System.out.println(set);
},String.valueOf(i)).start();
}
}
}
package com.juc.callable;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class CallableTest {
public static void main(String[] args) throws ExecutionException, InterruptedException {
MyThread thread = new MyThread();
FutureTask futureTask = new FutureTask(thread);
new Thread(futureTask,"A").start();
new Thread(futureTask,"B").start();//只打印了一个call(),结果会缓存,提高效率
System.out.println(futureTask.get());//可能产生阻塞,一般放在最后或者异步通信
}
}
class MyThread implements Callable<String>{
@Override
public String call() throws Exception {
System.out.println("call()");
return "1024";
}
}
结果会缓存,提高效率
可能产生阻塞,一般放在最后或者异步通信
8.2 CyclicBarrier
限流
package com.juc.rw;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class ReadWriteLockDemo {
public static void main(String[] args) {
MyCacheLock myCache = new MyCacheLock();
for (int i = 0; i < 5; i++) {
final int templ = i;
new Thread(()->{
myCache.put(templ+"",templ);
}).start();
}
for (int i = 0; i < 5; i++) {
final int templ = i;
new Thread(()->{
myCache.get(templ+"");
}).start();
}
}
}
class MyCache{
private volatile Map<String,Object> map = new HashMap<>();
public void put(String key,Object value){
System.out.println(Thread.currentThread().getName()+"=>写入"+key);
map.put(key,value);
System.out.println(Thread.currentThread().getName()+"=>写入ok");
}
public void get(String key){
System.out.println(Thread.currentThread().getName()+"=>读取"+key);
map.get(key);
System.out.println(Thread.currentThread().getName()+"=>读取ok");
}
}
class MyCacheLock{
private volatile Map<String,Object> map = new HashMap<>();
private ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
public void put(String key,Object value){
readWriteLock.writeLock().lock();
try {
System.out.println(Thread.currentThread().getName()+"=>写入"+key);
map.put(key,value);
System.out.println(Thread.currentThread().getName()+"=>写入ok");
}finally {
readWriteLock.writeLock().unlock();
}
}
public void get(String key){
readWriteLock.readLock().lock();
try {
System.out.println(Thread.currentThread().getName()+"=>读取"+key);
map.get(key);
System.out.println(Thread.currentThread().getName()+"=>读取ok");
}finally {
readWriteLock.readLock().unlock();
}
}
}
package com.juc.bq;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.TimeUnit;
public class Test {
public static void main(String[] args) throws InterruptedException {
test4();
}
public static void test1(){
ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue(3);
System.out.println(blockingQueue.add("a"));
System.out.println(blockingQueue.add("b"));
System.out.println(blockingQueue.add("c"));
// System.out.println(blockingQueue.add("d")); 多出指定的长度会抛出异常Queue full
System.out.println("==========================");
System.out.println(blockingQueue.remove());
System.out.println(blockingQueue.remove());
System.out.println(blockingQueue.remove());
// System.out.println(blockingQueue.remove());会抛出异常java.util.NoSuchElementException
}
public static void test2(){
ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue(3);
System.out.println(blockingQueue.offer("a"));
System.out.println(blockingQueue.offer("b"));
System.out.println(blockingQueue.offer("c"));
System.out.println(blockingQueue.offer("d"));
System.out.println("==========================");
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());
}
public static void test3() throws InterruptedException {
ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue(3);
blockingQueue.put("a");
blockingQueue.put("b");
blockingQueue.put("c");
// blockingQueue.put("d"); 阻塞
System.out.println("==========================");
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());
}
public static void test4() throws InterruptedException {
ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue(3);
System.out.println(blockingQueue.offer("a"));
System.out.println(blockingQueue.offer("b"));
System.out.println(blockingQueue.offer("c"));
System.out.println(blockingQueue.offer("d",2, TimeUnit.SECONDS));
System.out.println("==========================");
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll(2, TimeUnit.SECONDS));
}
}
package com.juc.bq;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.TimeUnit;
/**
* 只能放入一个元素,只有这个元素被去除才能放入其他元素
*/
public class SynchronousQueueDemo {
public static void main(String[] args) {
BlockingQueue<String> blockingQueue =new SynchronousQueue<>();
new Thread(()->{
try {
System.out.println(Thread.currentThread().getName()+" put 1");
blockingQueue.put("1");
System.out.println(Thread.currentThread().getName()+" put 2");
blockingQueue.put("2");
System.out.println(Thread.currentThread().getName()+" put 3");
blockingQueue.put("3");
} catch (InterruptedException e) {
e.printStackTrace();
}
},"t1").start();
new Thread(()->{
try {
TimeUnit.SECONDS.sleep(3);
System.out.println(Thread.currentThread().getName()+"=>"+blockingQueue.take());
TimeUnit.SECONDS.sleep(3);
System.out.println(Thread.currentThread().getName()+"=>"+blockingQueue.take());
TimeUnit.SECONDS.sleep(3);
System.out.println(Thread.currentThread().getName()+"=>"+blockingQueue.take());
} catch (InterruptedException e) {
e.printStackTrace();
}
},"t2").start();
}
}
package com.juc.forkjoin;
import java.util.concurrent.RecursiveTask;
/**
* 如何使用ForkJoin
* 1、forkJoinPool 通过它执行
* 2、forkJoinPool.execute(ForkJoinTask task)
* 3、计算类要继承 ForkJoinTask
*/
public class ForkJoinDemo extends RecursiveTask<Long> {
private Long start;
private Long end;
//临界值
private Long temp = 10000L;
public ForkJoinDemo(Long start, Long end, Long temp) {
this.start = start;
this.end = end;
this.temp = temp;
}
public ForkJoinDemo(Long start, Long end) {
this.start = start;
this.end = end;
}
/**
* The main computation performed by this task.
*
* @return the result of the computation
*/
@Override
protected Long compute() {
if(end-start<temp){
Long sum =0L;
for (Long i =start;i<end;i++){
sum+=1;
}
return sum;
}else{
Long middle = (start+end)/2;
ForkJoinDemo task1 = new ForkJoinDemo(start,middle);
task1.fork();//拆分任务把线程压入队列
ForkJoinDemo task2 = new ForkJoinDemo(middle,end);
task2.fork();
return task1.join() + task2.join();
}
}
}
package com.juc.forkjoin;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.stream.LongStream;
public class Test {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// test1();//8716
// test2();//7926
test3();//250
}
public static void test1(){
long start = System.currentTimeMillis();
Long sum =0L;
for (Long i =1l;i<10_0000_0000l;i++){
sum+=1;
}
long end = System.currentTimeMillis();
System.out.println("sum="+sum+" 时间:"+(end-start));
}
public static void test2() throws ExecutionException, InterruptedException {
long start = System.currentTimeMillis();
ForkJoinPool forkJoinPool = new ForkJoinPool();
ForkJoinTask<Long> task = new ForkJoinDemo(1l,10_0000_0000l);
ForkJoinTask<Long> submit = forkJoinPool.submit(task);
Long sum = submit.get();
long end = System.currentTimeMillis();
System.out.println("sum="+sum+" 时间:"+(end-start));
}
public static void test3(){
long start = System.currentTimeMillis();
Long sum = LongStream.rangeClosed(1l,10_0000_0000l).parallel().reduce(0,Long::sum);
long end = System.currentTimeMillis();
System.out.println("sum="+sum+" 时间:"+(end-start));
}
}
package com.juc.future;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
public class Demo01 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
CompletableFuture<Void> completableFuture = CompletableFuture.runAsync(()->{
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "CompletableFuture<Void>");
});
completableFuture.get();//阻塞获取执行的结果
System.out.println(Thread.currentThread().getName());
}
}
package com.juc.future;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
public class Demo02 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
CompletableFuture<Integer> completableFuture = CompletableFuture.supplyAsync(()->{
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "CompletableFuture<Integer>");
int i= 1/0;
return 1024;
});
System.out.println(12);//率先输出
System.out.println( completableFuture.whenComplete((t,u)->{
System.out.println("t=>"+t);//返回正常结果
System.out.println("u=>"+u);//错误信息
}).exceptionally((e)->{
System.out.println(e.getMessage());
return 233; // 返回错误结果
}).get());
}
}