Java--JUC--复习

  1. JUC是什么:java并发编程中使用的工具类
    1. java.util.concurrent
    2. java.util.concurrent.atomic
    3. java.util.concurrent.locks
  2. 什么是进程什么是线程
    1.   
        
  3. 什么是并发/并行
    1. 多个线程同时调用同一个资源类
    2. 同时做多件事
  4. 生产者消费和模式 为了防止虚假唤醒,我们应该使用while进行判断,每次都重新过一次安检,如果是if的换会出现虚假唤醒导致一加一减的业务逻辑失败。
  5.            
             package com.model.new_concurrent;
    
    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    /**
     * 启动:ABC三个线程
     * 要求A打印5次 ,b打印10次,c打印15次
     * 来十轮
     *
     * */
    
    class Print{
    
        private int num=1;
        Lock lock=new ReentrantLock();
        Condition condition_a=lock.newCondition();
        Condition condition_b=lock.newCondition();
        Condition condition_c=lock.newCondition();
    
         public void print_a(){
             lock.lock();
             try {
                 while(num!=1){
                     condition_a.await();
                 }
                 num++;
                 for (int i = 0; i < 5; i++) {
                     System.out.println(Thread.currentThread().getName()+"打印了"+i);
                 }
                 condition_b.signal();
    
             }catch (Exception e){
                 e.printStackTrace();
             }finally {
                 lock.unlock();
             }
    
         }
        public void print_b(){
            lock.lock();
            try {
                while(num!=2){
                    condition_b.await();
                }
                num++;
                for (int i = 0; i < 10; i++) {
                    System.out.println(Thread.currentThread().getName()+"打印了"+i);
                }
                condition_c.signal();
    
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                lock.unlock();
            }
    
        }
        public void print_c(){
            lock.lock();
            try {
                while(num!=3){
                    condition_c.await();
                }
                num=1;
                for (int i = 0; i < 15; i++) {
                    System.out.println(Thread.currentThread().getName()+"打印了"+i);
                }
                condition_a.signal();
    
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                lock.unlock();
            }
    
        }
    }
    public class Test01 {
        public static void main(String[] args) {
            Print print=new Print();
            new Thread(() ->{
                for (int i = 0; i < 10; i++) {
                    print.print_a();
                }
            },"A").start();
            new Thread(() ->{
                for (int i = 0; i < 10; i++) {
                    print.print_b();
                }
            },"B").start();
            new Thread(() ->{
                for (int i = 0; i < 10; i++) {
                    print.print_c();
                }
            },"C").start();
        }
    
    }

     

  6. 锁机制,同一个对象的所有同步方法不一把锁,所有对象的静态同步方法一把锁
  7.  集合线程的安全list,set,map
    1.   
      package com.model.new_concurrent;
      
      import jdk.nashorn.internal.ir.IdentNode;
      
      import java.util.ArrayList;
      import java.util.Collections;
      import java.util.List;
      import java.util.Vector;
      import java.util.concurrent.CopyOnWriteArrayList;
      
      public class NotSafe_ArrayList {
          public static void main(String[] args) {
      //        List<Integer> list=new ArrayList<>();
      //        List<Integer> list=new Vector<>();
      //        List<Integer> list= Collections.synchronizedList(new ArrayList<>());
              List<Integer> list= new CopyOnWriteArrayList();//写时复制
              new Thread(() ->{
                  for (int i = 0; i < 10; i++) {
                      list.add(i);
                      System.out.println(list);
                  }
      
              },"A").start();
             new Thread(() ->{
                 for (int i = 0; i < 10; i++) {
                     list.add(i);
                     System.out.println(list);
                 }
             },"B").start();
          }
      
      }

       

  8.  集合的线程安全使用写时复制的方式实现了线程安全,CopyonWritArraylist(),读写不在同一个同其中,写的时候将原来的复制一份,写完之后将 要来的容器的引用指向新版的集合,这样做的可以实现了并发的读而不需要加任何的锁,时读写分离的一种实现
  9. HashSet的底层时HashMap,只不过set的value值是一个Ojdect类型的常量,HashSet的add方法调用的就是map的put方法
  10. HashMap的底层是数组,列表,红黑树 
    1. package com.model.new_concurrent;
      
      import jdk.nashorn.internal.ir.IdentNode;
      
      import java.util.*;
      import java.util.concurrent.ConcurrentHashMap;
      import java.util.concurrent.CopyOnWriteArrayList;
      import java.util.concurrent.CopyOnWriteArraySet;
      
      public class NotSafe_ArrayList {
          public static void main(String[] args) {
      //        List<Integer> list=new ArrayList<>();
      //        List<Integer> list=new Vector<>();
      //        List<Integer> list= Collections.synchronizedList(new ArrayList<>());
              List<Integer> list= new CopyOnWriteArrayList();//写时复制
              new Thread(() ->{
                  for (int i = 0; i < 10; i++) {
                      list.add(i);
                      System.out.println(list);
                  }
      
              },"A").start();
             new Thread(() ->{
                 for (int i = 0; i < 10; i++) {
                     list.add(i);
                     System.out.println(list);
                 }
             },"B").start();
          }
      
      }
      class NotSafe_HashSet{
          public static void main(String[] args) {
      //        List<Integer> list=new ArrayList<>();
      //        List<Integer> list=new Vector<>();
      //        List<Integer> list= Collections.synchronizedList(new ArrayList<>());
              Set<Integer> set= new CopyOnWriteArraySet();//写时复制
              new Thread(() ->{
                  for (int i = 0; i < 10; i++) {
                      set.add(i);
                      System.out.println(set);
                  }
      
              },"A").start();
              new Thread(() ->{
                  for (int i = 0; i < 10; i++) {
                      set.add(i);
                      System.out.println(set);
                  }
              },"B").start();
          }
      }
      class NotSafe_HashMap{
          public static void main(String[] args) {
      //        List<Integer> list=new ArrayList<>();
      //        List<Integer> list=new Vector<>();
      //        List<Integer> list= Collections.synchronizedList(new ArrayList<>());
              Map<String,Object> map=new ConcurrentHashMap();//写时复制
              new Thread(() ->{
                  for (int i = 0; i < 10; i++) {
                      map.put(UUID.randomUUID().toString().substring(0,6),i);
                      System.out.println(map);
                  }
      
              },"A").start();
              new Thread(() ->{
                  for (int i = 0; i < 10; i++) {
                      map.put(UUID.randomUUID().toString().substring(0,6),i);
                      System.out.println(map);
                  }
              },"B").start();
          }
      }
  11. 线程实现的第三种方式Callable
    1. package com.model.new_concurrent;
      
      import java.util.concurrent.Callable;
      import java.util.concurrent.ExecutionException;
      import java.util.concurrent.FutureTask;
      import java.util.concurrent.TimeUnit;
      
      class MyThread01 extends Thread{
          @Override
          public void run() {
              super.run();
          }
      }
      class MyThread02 implements Runnable{
          @Override
          public void run() {
      
          }
      }
      class MyThread03 implements Callable<Integer> {
      
          @Override
          public Integer call() throws Exception {
              System.out.println("come in *********");
              TimeUnit.SECONDS.sleep(4);
              return 1024;
          }
      }
      
      public class CallableTest {
      /**
       * sleep和wait的区别:
       * 1.是否有异常
       * 2.使用位置
       * 3.是否释放锁
       * 4.所属类不同
       *
       * Runnable和Callable的区别:
       *  1.Callable是第三种实现线程方法,Runnable是第二种实现线程的方法
       *  2.方法不同:一个叫run方法 ,一个叫call方法
       *  3.call方法右异常,run方法无异常
       *  4.call方法有返回值,run方法无返回值
       *
       * */
          public static void main(String[] args) throws ExecutionException, InterruptedException {
      
      //        FutureTask 有构造方法可以接受实现了Runnable或者是Callable的接口的类
      //        FutureTask又是Runnable接口的子类(RunnableFuture)的实现类,
      //        Thread()可以接手Runnable接口的实现类,所有FutureTask的对象可以传入,实现了Runnable和CallAble接口的联系,线程实现成功
      //        Callable实现的线程:耗时的线程对于主线程来说,如果等待可能会阻塞整体的的推进,整个进程耗时严重
      //        使用了Callable实现的线程我们可以为他们另开一个线程,让这个耗时的线程进行着,而我们的主线程不会等待,而是继续往下推进执行,
      //        当耗时的线程执行完毕之后将放回值返回给主线程即可。这样降低了我们整个程序的执行时间
              FutureTask futureTask=new FutureTask(new MyThread03());
      
              new Thread(futureTask,"A").start();
              //不管调用几次,只有一个futureTask对象会产生缓存,最终结果执行一次
              new Thread(futureTask,"B").start();
      
              System.out.println("****** main线程完成了");
              System.out.println(futureTask.get());
              //获取返回值,要在程序的最后调用返回值,如果我们刚开启耗时线程,他还没有计算出结果。
              // 我们就去调用结果,会造成我们进入这个线程,就要等待他计算完才能出这个线程,造成阻塞,无法达到我们预期的结果
      
          }
      }

       

        
  12. CountDownLatCh的使用(做减法,六个线程都结束,才能完成主线程)
    1.   
      package com.model.new_concurrent;
      
      import java.util.concurrent.CountDownLatch;
      
      class CloseDoor{
          public void close(){
              System.out.println(Thread.currentThread().getName()+"离开可教室");
          }
      }
      /**
       * 实现了一个 等6个进程都完成之后主进程才能结束的逻辑
       * CountDownLatch 
       *
       * */
      public class CountDownLatchDemo {
          public static void main(String[] args) throws InterruptedException {
              CountDownLatch countDownLatch=new CountDownLatch(6);
              CloseDoor closeDoor=new CloseDoor();
              for (int i=1;i<=6;i++){
                  new Thread(() ->{
                      closeDoor.close();
                      countDownLatch.countDown();
                  },String.valueOf(i)).start();
              }
              countDownLatch.await();
              System.out.println("班长关门了***");
      
          }
      }

       

          
  13. CyclicBarrier工具类的使用:(做加法:需要完成七个进程才能进行下面的进程)
    1. package com.model.new_concurrent;
      
      import java.util.concurrent.BrokenBarrierException;
      import java.util.concurrent.CyclicBarrier;
      
      /**
       *
       *
       * */
      public class CyclicBarrierDemo {
          /**
           * 实现了 完成7个及龙珠的线程之后才能进行 召唤神龙的线程的 业务逻辑(都是非主线程)
           * */
          public static void main(String[] args) {
      
              CyclicBarrier cyclicBarrier=new CyclicBarrier(7,()->{
                  System.out.println("收集了7颗龙珠,召唤神龙");
              });
              for (int i=1;i<=7;i++){
                  final int t=i;
                  new Thread(() ->{
                      System.out.println(Thread.currentThread().getName()+"线程收集了第"+t+"颗龙珠");
                      try {
                          cyclicBarrier.await();
                      } catch (InterruptedException e) {
                          e.printStackTrace();
                      } catch (BrokenBarrierException e) {
                          e.printStackTrace();
                      }
                  },String.valueOf(i)).start();
              }
          }
      }

       

          
  14.  Semaphore(红绿灯的使用):多个线程争抢多个资源,
    1. package com.model.new_concurrent;
      
      import java.util.concurrent.Semaphore;
      import java.util.concurrent.TimeUnit;
      
      public class SemaphoreDemo {
          /**
           * 用于实现多个线程,争抢多个资源的情况(限流)
           * 当资源数量为1是,就像相当于在资源类中加锁一样的情况
           * */
          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()+"抢到了资源");
                          TimeUnit.SECONDS.sleep(3);
                          semaphore.release();
                          System.out.println(Thread.currentThread().getName()+"使用完毕 ,释放了资源");
                      } catch (InterruptedException e) {
                          e.printStackTrace();
                      }
                  },String.valueOf(i)).start();
              }
      
          }
      } 
  15. Condition:Condition condition=lock.newCondition(); 指定某一个特定的下一个要执行的线程;callable接口,实现线程的第三种方式(要使用futureTask类);
  16. collection:set和list的实现的接口;collections:是一个实现排序加索,工具类            
posted @ 2021-06-06 21:03  张紫韩  阅读(53)  评论(0编辑  收藏  举报