juc//java工具类

juc//java工具类

在这里插入图片描述

小结:

java工具类,lock和synchronize的使用 Lock lock=new ReentrantLock();

private Condition condition1=lock.newCondition();可以精准控制线程

8锁现象等
这个是看b站狂神视频总结的一些笔记,用于日后复习。

java查看线程的几个状态的类

//java查看线程转态
//Thread.State.
public enum State {
        //新建
        NEW,
        RUNNABLE,
        BLOCKED,
        WAITING,
		//超时等待
        TIMED_WAITING,
        TERMINATED;
    }
synchronized
//实现订单实例
import java.util.Scanner;

public class test {
    public static void main(String[] args) {
        miapiao m=new miapiao();
        Thread t=new Thread(()->{
            for (int i=0;i<40;i++){
                m.mai();
            }
            //java查看线程转态
            //Thread.State.
        },"a");
        new Thread(()->{
            for (int i=0;i<40;i++){
                m.mai();
            }
        },"b").start();
        new Thread(()->{
            for (int i=0;i<40;i++){
                m.mai();
            }
        },"c").start();


    }
}

class miapiao{
    private int num=20;
    synchronized void  mai(){
        if(num>0){
            System.out.println(Thread.currentThread().getName()+"票数"+num--+"剩余"+num);
        }
    }
}

lock锁

//创建锁对象
//锁住操作代码
//解锁

class miapiao2{
    //创建锁对象
    //锁住操作代码
    //解锁
    private int num=20;
    Lock lock=new ReentrantLock();
    public void  mai(){
        lock.lock();
        try {
            if(num>0){
                System.out.println(Thread.currentThread().getName()+"票数"+num--+"剩余"+num);
            }

        }catch (Exception e){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }

    }
}

lock和synchronize的区别

synchronize 内置关键字 lock是一个java类

synchronize 无法判断获取锁的状态,lock可以判断是否获取了锁

synchronize会释放锁,lock需要手动释放,如果不释放就会死锁

synchronize线程1 获得锁,线程2就会等待,lock不一定会等待

synchronize可重入锁,不可以中断锁,非公平;lock可以判断锁

synchronize适合少量代码同步,;lock适合锁大量同步代码

锁是什么,如何判断锁的是谁

1.生产者消费者问题
package pc;
public class pc {
    public static void main(String[] args) {
        Data data=new Data();
        new Thread(()->{
            for (int i=0;i<10;i++){
                try {
                    data.increment();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"a").start();
        new Thread(()->{
            for (int i=0;i<10;i++){
                try {
                    data.decrement();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"b").start();

    }
}
class Data{
    private int number=0;
    public synchronized void increment() throws InterruptedException {
        if (number!=0){
            this.wait();
        }
        number++;
        System.out.println(Thread.currentThread().getName()+"=>"+number);
        this.notifyAll();
    }
    public synchronized void decrement() throws InterruptedException {
        if (number==0){
            this.wait();
        }
        number--;
        System.out.println(Thread.currentThread().getName()+"=>"+number);
        this.notifyAll();
    }
}

存在问题

虚假唤醒,等待应该穿在while中

要把if换成while

2.新版本pc问题使用lock解决
package pc;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class pc2 {
    public static void main(String[] args) {
        Data2 data2=new Data2();
        new Thread(()->{
            for (int i=0;i<10;i++){
                try {
                    data2.increment();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"a").start();
        new Thread(()->{
            for (int i=0;i<10;i++){
                try {
                    data2.decrement();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"b").start();

    }
}
//ctrl+alt+t快捷键
class Data2{
    private int number=0;
    Lock lock=new ReentrantLock();
    Condition condition=lock.newCondition();
//    condition.await();等待
//    condition.signalAll();唤醒
    public  void increment() throws InterruptedException {
        lock.lock();
        try {
            if (number!=0){
                condition.await();
            }
            number++;
            System.out.println(Thread.currentThread().getName()+"=>"+number);
            condition.signalAll();

        }catch (Exception e){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }


    }
    public  void decrement() throws InterruptedException {
        lock.lock();
        try {
            if (number==0){
                condition.await();
            }
            number--;
            System.out.println(Thread.currentThread().getName()+"=>"+number);
            condition.signalAll();
        }catch (Exception e ){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }

    }
}

3.condition精准唤醒线程
package pc;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class test3 {
    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 number=1;
    public void printa(){
        lock.lock();
        try {
            //业务,贩毒案,执行,通知
            while (number!=1){
                condition1.await();
            }
            System.out.println(Thread.currentThread().getName()+"===>>>aaa");
            number=2;
            condition2.signal();

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }

    }
    public void printb(){
        lock.lock();
        try {
            //业务,贩毒案,执行,通知
            while (number!=2){
                condition2.await();
            }
            System.out.println(Thread.currentThread().getName()+"===>>>aaa");
            number=3;
            condition3.signal();

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }

    }
    public void printc(){
        lock.lock();
        try {
            //业务,贩毒案,执行,通知
            while (number!=3){
                condition3.await();
            }
            System.out.println(Thread.currentThread().getName()+"===>>>cccc");
            number=1;
            condition1.signal();

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }

    }
}
4.8锁现象

深刻理解锁

说到底,就是看锁的是不是同一个对象,如果不是同一个对象象就要不需要等待,如果是同一个对象就要等待。

new

static class

如果是同一个锁就看谁先获得,如果不是同一个锁,就看休眠时间。

5.集合类不安全

list不安全

package unsafelist;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.CopyOnWriteArrayList;

public class ListTest {
    public static void main(String[] args) {
//        List<String> list=new ArrayList<>();
        //线程安全
//        1.List<String> list= Collections.synchronizedList(new ArrayList<>());
        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);
            }).start();
        }
    }
}

set

package unsafelist;

import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;

public class SetTest {
    public static void main(String[] args) {
//        Set<String> set=new HashSet<>();
//        Set<String> set= Collections.synchronizedSet(new HashSet<>());
//        Set<String> set=new CopyOnWriteArraySet<>();

        //hashset底层就是hashmap
        //        public boolean add(E e) {
//            return map.put(e, PRESENT)==null;
//        }
        Set<String> set=new CopyOnWriteArraySet<>();
        for (int i=0;i<10;i++){
            new Thread(()->{
                set.add(UUID.randomUUID().toString().substring(0,5));
                System.out.println(set);
            }).start();
        }
    }
}

map

map

默认等价? new hashmap(16,0.75);

6.callable
package callabletest;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class Test {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        Mythread mythread=new Mythread();
        FutureTask futureTask=new FutureTask(mythread);
        new Thread(futureTask,"a").start();
        Integer a=(Integer)futureTask.get();
        System.out.println(a);
    }
}
class Mythread implements Callable<Integer>{

    @Override
    public Integer call() throws Exception {
        System.out.println("call");
        return 1024;
    }
}
7.常用的辅助类
CountDownLatch减法计数器
package callabletest;

import java.util.concurrent.CountDownLatch;
//减法计数器
public class CountDownLatch2 {
    public static void main(String[] args) throws InterruptedException {
        CountDownLatch countDownLatch=new CountDownLatch(6);
        for (int i=1;i<=6;i++){
            new Thread(()->{
                System.out.println(Thread.currentThread().getName()+"go out");
                countDownLatch.countDown();
            },String.valueOf(i)).start();
        }
        countDownLatch.wait();
        System.out.println("结束");
        //countDownLatch.countDown();数量-1
        //当-到0就会countDownLatch.wait();唤醒

    }
}

CyclicBarrier加法计数器
package callabletest;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class CyclicBarriertest {
    //加法计数器
    public static void main(String[] args) {
        CyclicBarrier cyclicBarrier=new CyclicBarrier(7,()->{
            System.out.println("数量到达");
        });
        for (int i=1;i<=7;i++){
            final int tmp=i;
            new Thread(()->{
                //在lambda中拿到上面的i的变量通过中间变量final
                System.out.println(tmp+Thread.currentThread().getName());
                try {
                    cyclicBarrier.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            }).start();
        }

    }
}


Semaphore信号量
package callabletest;

import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

public class Semaphoretest {
    //信号量,限流
    public static void main(String[] args) {
        Semaphore semaphore=new Semaphore(3);
        for (int i=1;i<=6;i++){
            new Thread(()->{
                try {
                    //获得
                    semaphore.acquire();
                    System.out.println(Thread.currentThread().getName()+"---get");
                    TimeUnit.SECONDS.sleep(2);
                    System.out.println(Thread.currentThread().getName()+"---leave");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {
                    //释放
                    semaphore.release();
                }

            },String.valueOf(i)).start();
        }

    }
}

8.读写锁ReadWriteLock

ReadWriteLock

写锁只能被一个线程占用

读锁可以被同时占用

package ReadWriteLocktest;

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=1;i<=6;i++){
            final int tmp=i;
            new Thread(()->{
                myCache.put(tmp+"",tmp+"");
            },String.valueOf(i)).start();
        }
        for (int i=1;i<=6;i++){
            final int tmp=i;
            new Thread(()->{
                myCache.get(tmp+"");
            },String.valueOf(i)).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 ReadWriteLock readWriteLock=new ReentrantReadWriteLock();

    private volatile Map<String,Object> map=new HashMap<>();
    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" + "");
        } catch (Exception e) {
            e.printStackTrace();
        } 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" + "");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            readWriteLock.readLock().unlock();
        }
    }
}
10阻塞队列

阻塞:如果队列阻塞,就必须等待

队列

什么情况下用阻塞队列

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AUtHHBfz-1638085874752)(C:\Users\gym\AppData\Roaming\Typora\typora-user-images\image-20211126144822704.png)]

四组api

抛出异常

不会抛出异常

阻塞

超时等待

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-G1aGDBwB-1638085874755)(C:\Users\gym\AppData\Roaming\Typora\typora-user-images\image-20211126150115867.png)]

package BlockingQueueTest;

import java.util.concurrent.ArrayBlockingQueue;

public class BlockingQueueDemo {
    public static void main(String[] args) {
        BlockingQueueDemo.test1();
    }
    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("----------------------");
        System.out.println(blockingQueue.remove());
        System.out.println(blockingQueue.remove());
        System.out.println(blockingQueue.remove());
        //再-就异常
        //.poll()有返回值,不报错


    }
}

同步队列SynchronousQueue

进一个必须取出一个

package BlockingQueueTest;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.SynchronousQueue;

public class SynchronousQueueTest {
    public static void main(String[] args) {
        BlockingQueue<String> synchronousQueue=new SynchronousQueue<>();
        new Thread(()->{
            try {
                System.out.println(Thread.currentThread().getName()+"put 1");
                synchronousQueue.put("1");
                System.out.println(Thread.currentThread().getName()+"put 2");
                synchronousQueue.put("2");
                System.out.println(Thread.currentThread().getName()+"put 3");
                synchronousQueue.put("3");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"t1").start();

        new Thread(()->{
            try {
                System.out.println(Thread.currentThread().getName()+"----"+synchronousQueue.take());
                System.out.println(Thread.currentThread().getName()+"---"+synchronousQueue.take());
                System.out.println(Thread.currentThread().getName()+"--"+synchronousQueue.take());

            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"t2").start();
    }
}

10线程池

池化技术

程序的运行,本质,占用痛资源!优化资源的使用,=》赤化技术

降低资源的消耗

提高响应速度

方便管理

线程复用,可以控制最大并发数,管理线程

3大方法7大参数4种策略

package pool;

import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
//Executors三大方法
public class TestPool {
    public static void main(String[] args) {
//        Executors.newSingleThreadExecutor();//单个线程
//        Executors.newFixedThreadPool(5);
//        Executors.newCachedThreadPool();//可伸缩线程池
//        ExecutorService executorService=Executors.newSingleThreadExecutor();
        ExecutorService executorService=Executors.newFixedThreadPool(5);
        try {
            for (int i=1;i<10;i++){
                executorService.execute(()->{
                    System.out.println(Thread.currentThread().getName()+"ok");
                });
            }
        } finally {
            executorService.shutdown();

        }


    }

}

7大参数


public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }
public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), defaultHandler);
    }
package pool;

import java.util.concurrent.*;

//Executors三大方法
public class TestPool {
    public static void main(String[] args) {
        Executors.newSingleThreadExecutor();//单个线程
//        Executors.newFixedThreadPool(5);
//        Executors.newCachedThreadPool();//可伸缩线程池
//        ExecutorService executorService=Executors.newSingleThreadExecutor();
//        ExecutorService executorService=Executors.newFixedThreadPool(5);
        //自定义线程池
        ExecutorService executorService=new ThreadPoolExecutor(
                2,
                5,
                3,
                TimeUnit.SECONDS,
                new LinkedBlockingDeque<>(),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy()//拒绝策略,满了就抛出异常,四种策略
                );
        try {
            for (int i=1;i<10;i++){
                executorService.execute(()->{
                    System.out.println(Thread.currentThread().getName()+"ok");
                });
            }
        } finally {
            executorService.shutdown();

        }


    }

}

CPU密集型:几核就是几,cpu效率最高

Runtime.getRuntime().availableProcessors();

io密集型:判断你的程序中io 的线程

11四大函数式接口

lambda表达式,链式编程,函数式接口,Stream流式计算

函数式接口:只有一个方法的接口

//Runable
public abstract void run();

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RHosgqkX-1638085874758)(C:\Users\gym\AppData\Roaming\Typora\typora-user-images\image-20211126181620267.png)]

四大原生函数式接口

package hanshu;

import java.util.function.Function;

public class FunctionTest {
    public static void main(String[] args) {
        //一个输入一个输出
        //只要是函数式接口就诶lambda
//        Function function=new Function<String,String>(){
//            @Override
//            public String apply(String o) {
//                return o;
//            }
//        };
        Function function=(str)->{ return str; };
        System.out.println(function.apply("123"));
    }
}

断定型接口

package hanshu;

import java.util.function.Predicate;

public class PredicateTest {
    //断定型接口
    public static void main(String[] args) {
//        Predicate predicate=new Predicate<String>() {
//            @Override
//            public boolean test(String o) {
//                return o.isEmpty();
//            }
//        };
        Predicate<String> predicate=(str)->{return str.isEmpty();};
        System.out.println(predicate.test("123"));

    }
}

消费型接口,供给型接口

package hanshu;

import java.util.function.Consumer;
import java.util.function.Supplier;

public class ConsumerTest {
    public static void main(String[] args) {
        //消费型接口
        Consumer consumer=new Consumer<String>() {
            @Override
            public void accept(String o) {
                System.out.println(o);
            }
        };
        Consumer<String> consumer1=(str)->{ System.out.println(str); };
        consumer1.accept("123");
        Supplier supplier=new Supplier<Integer>() {
            @Override
            public Integer get() {
                return 1204;
            }
        };
        Supplier<Integer> supplier1=()->{return  1024;};
        System.out.println(supplier1.get());
    }
}

12Stream流式计算

大数据=存储+计算

流式计算

package stream;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Util {
    public static void main(String[] args) {
        User u1=new User(1,"a",21);
        User u2=new User(2,"b",22);
        User u3=new User(3,"c",23);
        User u4=new User(4,"d",24);
        User u5=new User(6,"e",25);
        //集合用于存储
        List<User> list= Arrays.asList(u1,u2,u3,u4,u5);

        //stream计算
        //链式编程
        list.stream().filter(u->{return  u.getId()%2==0;})
                .filter(u->{return  u.getAge()>23;})
                .map(u->{return  u.getName().toUpperCase();})
                .sorted((uu1,uu2)->{return  uu2.compareTo(uu1);})
                .limit(1)
                .forEach(System.out::println);

    }
}

13ForkJoin

什么是ForkJoin

1.7之后出来的,并发执行任务,提高效率,大数据量

特点:工作窃取

三种对大数据的处理方式

package 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 {
//        Test.test1();//3768
//        Test.test2();//5231
        Test.test3();//497
    }
    public static void test1(){
        Long sum=0L;
        long start=System.currentTimeMillis();
        for (long i=1L;i<=10_0000_0000L;i++){
            sum+=i;
        }
        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> tasl=new ForkjoinTest(0L,10_0000_0000L);
        ForkJoinTask<Long> submit=forkJoinPool.submit(tasl);
        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(0L,10_0000_0000L).parallel().reduce(0,Long::sum);
        long end=System.currentTimeMillis();
        System.out.println("sum="+sum+"时间="+(end-start));
    }
}

14异步回调

Future

package future;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

public class FutureTest {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //发起一个请求
        //没有返回值的异步回调
//        CompletableFuture<Void> completableFuture=CompletableFuture.runAsync(()->{
//            try {
//                TimeUnit.SECONDS.sleep(2);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//            System.out.println(Thread.currentThread().getName()+"runAsync+>voi");
//        });
//        System.out.println("1111");
//        completableFuture.get();//获得执行结果
        CompletableFuture<Integer> completableFuture=CompletableFuture.supplyAsync(()->{
            System.out.println(Thread.currentThread().getName()+"runAsync+>integer");
            return 1024;
        });
        System.out.println("123");
        completableFuture.get();
    }
}

15理解jmm

对volatile的理解

volatile是java轻量级的同步机制

1.可见性

2.不保证原子性

3.禁止指令重排

jmm:java内存模型

关于jmm的一些同步约定

1线程解锁前,必须把共享变量理立刻刷回主存

2线程加锁前,必须读取主存中最新的值

3.加锁和解锁是同一个锁

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aXxSP87E-1638085874762)(C:\Users\gym\AppData\Roaming\Typora\typora-user-images\image-20211127174640649.png)]

内存模型-同步八种操作
1:lock: 把主内存变量标识为一条线程独占,此时不允许其他线程对此变量进行读写。
2:unlock:解锁一个主内存变量。
3:read: 把一个主内存变量值读入到线程的工作内存,强调的是读入这个过程。
4:load: 把read到变量值保存到线程工作内存中作为变量副本,强调的是读入的值的保存过程。
5:use: 线程执行期间,把工作内存中的变量值传给字节码执行引擎。
6:assign(赋值):字节码执行引擎把运算结果传回工作内存,赋值给工作内存中的结果变量。
7:store: 把工作内存中的变量值传送到主内存,强调传送的过程。
8:write: 把store传送进来的变量值写入主内存的变量中,强调保存的过程。

16volatile

保证可见性

package jmm;

import java.util.concurrent.TimeUnit;

public class JmmTest {
    //可见性
    private volatile static  int num=0;
    public static void main(String[] args) {
        //线程不知道主存的值已经改变了
        new Thread(()->{
            while (num==0){

            }
        }).start();
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        num=1;
        System.out.println(num);

    }
}

不保证原子性

线程a执行任务时不能被分割

package jmm;

public class Test2 {
    private static volatile int num=0;
    public static   void add(){
        num++;
    }
    public static void main(String[] args) {
        for (int i=1;i<20;i++){
            new Thread(()->{
                for (int j=1;j<=1000;j++){
                    add();
                }
            }).start();
        }
        while (Thread.activeCount()>2){
            Thread.yield();
        }
        System.out.println(Thread.currentThread().getName()+"---"+num);
    }
}

不加lock和synchronize保证原子性

package jmm;

import java.util.concurrent.atomic.AtomicInteger;

public class Test2 {
    private static volatile AtomicInteger num=new AtomicInteger();
    public static   void add(){
        num.getAndIncrement();//AtomicInteger+1
    }
    public static void main(String[] args) {
        for (int i=1;i<=20;i++){
            new Thread(()->{
                for (int j=1;j<=1000;j++){
                    add();
                }
            }).start();
        }
        while (Thread.activeCount()>2){
            Thread.yield();
        }
        System.out.println(Thread.currentThread().getName()+"---"+num);
    }
}

17指令重排

源代码》编译器优化的重排》指令并行也可能会重排》内存系统会重排》执行

写的程序不一定按照顺序执行,系统会判断关联性再执行

volatile可以防止指令重排

18单例模式
19CAS 比较并交换

通过unsafe类操作内存,效率更快比较工作内存中的值和主内存中的值,这个值是期望的,那么就执行操作

缺:

自旋的

循环耗时

一次性只能保证一个共享变量的值

aba问题

package cas;

import java.util.concurrent.atomic.AtomicInteger;

public class Test {
    public static void main(String[] args) {
        //cas:比较和交换
        AtomicInteger atomicInteger=new AtomicInteger(2020);
        atomicInteger.compareAndSet(2020,2021);
        System.out.println(atomicInteger.get());
        atomicInteger.compareAndSet(2020,2021);
        System.out.println(atomicInteger.get());
    }
}

ABA

已经动过手脚的数据

package cas;

import java.util.concurrent.atomic.AtomicInteger;

public class Test {
    public static void main(String[] args) {
        //cas:比较和交换
        AtomicInteger atomicInteger=new AtomicInteger(2020);
        //捣乱
        atomicInteger.compareAndSet(2020,2021);
        System.out.println(atomicInteger.get());
        atomicInteger.compareAndSet(2021,2020);
        System.out.println(atomicInteger.get());
        atomicInteger.compareAndSet(2020,6666);
        System.out.println(atomicInteger.get());
    }
}

原子引用
AtomicStampedReference<Integer> atomicStampedReference=new AtomicStampedReference<>(2020,1);

通过版本号控制

公平锁:不能插队

非公平锁:能插队

可重入锁

递归锁

拿到了外面的锁,就拿到了里面的锁

锁必须配对

//synchronized
package lock8;

public class Test3 {
    public static void main(String[] args) {
        PhoneTest phone=new PhoneTest();
        new Thread(()->{
            phone.sms();

        },"A").start();
        new Thread(()->{
            phone.sms();
        },"B").start();

    }
}
class PhoneTest{
    public synchronized void sms(){
        System.out.println("smm-----------");
        call();
    }
    public synchronized void call(){
        System.out.println("call-----------");
    }
}
//lock
package lock8;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Test4 {
    public static void main(String[] args) {
        PhoneTest2 phone=new PhoneTest2();
        new Thread(()->{
            phone.sms();

        },"A").start();
        new Thread(()->{
            phone.sms();
        },"B").start();

    }
}
class PhoneTest2{
    Lock lock=new ReentrantLock();
    public  void sms(){
        lock.lock();
        try {
            System.out.println("smm-----------");
            call();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
    public  void call(){

        lock.lock();
        try {
            System.out.println("call-----------");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}
自旋锁

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1tjpL4mJ-1638085874764)(C:\Users\gym\AppData\Roaming\Typora\typora-user-images\image-20211127191606503.png)]

package lock8;

import java.util.concurrent.atomic.AtomicReference;

public class Test5 {

    AtomicReference<Thread> atomicReference=new AtomicReference<>();
    public  void  myLock(){
        Thread thread= Thread.currentThread();
        System.out.println(Thread.currentThread().getName()+"====>mylock");
        //自旋锁
        while (!atomicReference.compareAndSet(null,thread)){}

    }
    public  void  unmyLock(){
        Thread thread= Thread.currentThread();
        System.out.println(Thread.currentThread().getName()+"====>unmylock");
        //
        atomicReference.compareAndSet(thread,null);


    }

}

死锁排查

试图获得对象的锁

日志

jps

jstack+进程号

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7WowZwIg-1638085874766)(C:\Users\gym\AppData\Roaming\Typora\typora-user-images\image-20211127195541981.png)]

s(){
lock.lock();
try {
System.out.println(“smm-----------”);
call();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void call(){

    lock.lock();
    try {
        System.out.println("call-----------");
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        lock.unlock();
    }
}

}


##### **自旋锁**

[外链图片转存中...(img-1tjpL4mJ-1638085874764)]

```java
package lock8;

import java.util.concurrent.atomic.AtomicReference;

public class Test5 {

    AtomicReference<Thread> atomicReference=new AtomicReference<>();
    public  void  myLock(){
        Thread thread= Thread.currentThread();
        System.out.println(Thread.currentThread().getName()+"====>mylock");
        //自旋锁
        while (!atomicReference.compareAndSet(null,thread)){}

    }
    public  void  unmyLock(){
        Thread thread= Thread.currentThread();
        System.out.println(Thread.currentThread().getName()+"====>unmylock");
        //
        atomicReference.compareAndSet(thread,null);


    }

}

死锁排查

试图获得对象的锁

日志

jps

jstack+进程号

[外链图片转存中…(img-7WowZwIg-1638085874766)]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

谷咕咕

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值