什么是JUC

1.java.util工具包 包 分类

业务:普通的线程代码 Thread

Runnable 没有返回值、效率相比Callable相对较低

2.线程和进程

进程:一个程序。QQ.exe,Music.exe 程序的集合

一个进程往往可以包含多个线程,至少包含一个!

Java默认有几个线程:2个 main、GC

线程:开了一个进程Typora,写字(一个线程在输入),自动保存(线程负责的)

对于Java而言开启线程的方式:Thread、Runnable、Callable

Java真的可以开启线程吗? 开不了

    public synchronized void start() {
         /**
          * This method is not invoked for the main method thread or "system"
          * group threads created/set up by the VM. Any new functionality added
          * to this method in the future may have to also be added to the VM.
          *
          * A zero status value corresponds to state "NEW".
          */
         if (threadStatus != 0)
             throw new IllegalThreadStateException();
 ​
         /* Notify the group that this thread is about to be started
          * so that it can be added to the group's list of threads
          * and the group's unstarted count can be decremented. */
         group.add(this);
 ​
         boolean started = false;
         try {
             start0();
             started = true;
        } finally {
             try {
                 if (!started) {
                     group.threadStartFailed(this);
                }
            } catch (Throwable ignore) {
                 /* do nothing. If start0 threw a Throwable then
                   it will be passed up the call stack */
            }
        }
    }
 //本地方法 调用底层的C++,java是运行在虚拟机上的,无法操作硬件
     private native void start0();
 ​

并发 、并行

并发编程:并发 并行

并发(多线程操作桶一个资源)

并行(多个人一起行走)

并发:若CPU只有一核(一瞬间只能处理一个东西),想要模拟出来多条线程,则需要快速交替。

并行:若CPU多核,多个线程可以同时执行,用线程池提高性能

 package com.kuang.demo06;
 ​
 public class Test1 {
     public static void main(String[] args) {
 ​
         //获取CPU的核数
         System.out.println(Runtime.getRuntime().availableProcessors());
 ​
 ​
    }
 }
 ​

并发编程的本质:充分利用CPU的资源

线程有几个状态

  public enum State {
         /**
          * Thread state for a thread which has not yet started.
          */
      //线程新生
         NEW,
 ​
         /**
          * Thread state for a runnable thread. A thread in the runnable
          * state is executing in the Java virtual machine but it may
          * be waiting for other resources from the operating system
          * such as processor.
          */
      //运行状态
         RUNNABLE,
 ​
         /**
          * Thread state for a thread blocked waiting for a monitor lock.
          * A thread in the blocked state is waiting for a monitor lock
          * to enter a synchronized block/method or
          * reenter a synchronized block/method after calling
          * {@link Object#wait() Object.wait}.
          */
      //阻塞
         BLOCKED,
 ​
         /**
          * Thread state for a waiting thread.
          * A thread is in the waiting state due to calling one of the
          * following methods:
          * <ul>
          *   <li>{@link Object#wait() Object.wait} with no timeout</li>
          *   <li>{@link #join() Thread.join} with no timeout</li>
          *   <li>{@link LockSupport#park() LockSupport.park}</li>
          * </ul>
          *
          * <p>A thread in the waiting state is waiting for another thread to
          * perform a particular action.
          *
          * For example, a thread that has called <tt>Object.wait()</tt>
          * on an object is waiting for another thread to call
          * <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on
          * that object. A thread that has called <tt>Thread.join()</tt>
          * is waiting for a specified thread to terminate.
          */
      //等待  
         WAITING,
 ​
         /**
          * Thread state for a waiting thread with a specified waiting time.
          * A thread is in the timed waiting state due to calling one of
          * the following methods with a specified positive waiting time:
          * <ul>
          *   <li>{@link #sleep Thread.sleep}</li>
          *   <li>{@link Object#wait(long) Object.wait} with timeout</li>
          *   <li>{@link #join(long) Thread.join} with timeout</li>
          *   <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>
          *   <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>
          * </ul>
          */
      //超时等待 死死的等
         TIMED_WAITING,
 ​
         /**
          * Thread state for a terminated thread.
          * The thread has completed execution.
          */
      //终止
         TERMINATED;
    }
 ​

wait/sleep区别

1.来自不同的类

wait=>Object

sleep=>Thread

  TimeUnit.DAYS.sleep(1);
  TimeUnit.SECONDS.sleep(2);

2关于锁的释放

wait会释放锁

sleep不会释放锁 抱着锁睡觉不会放锁

3使用范围不同

wait:必须在同步代码块中

sleep:可以在任何地方

4 是否需要捕获异常

wait不需要捕获异常

sleep必须要捕获异常

3、Lock锁(重点)

传统synchronized

 package com.kuang.demo06;
 //基本的卖票例子
 /**
  * 真正的多线程开发,公司中的开发,降低耦合性
  *线程就是一个单独的资源类,没有任何附属的操作
  * 1.属性、方法
  */
 ​
 public class SaleTicketDemo01 {
     public static void main(String[] args) {
       //并发:多线程操作同一个资源类,把资源丢入线程
         Ticket ticket = new Ticket();
         //@FunctionalInterface 函数式接口,jdk1.8后 lambda表达式(参数)->{代码}
         new Thread(()->{
             for (int i = 0; i < 40; i++) {
                 ticket.sale();
            }
 ​
        },"A").start();
         new Thread(()->{
             for (int i = 0; i < 40; i++) {
                 ticket.sale();
            }
        },"B").start();
         new Thread(()->{
             for (int i = 0; i < 40; i++) {
                 ticket.sale();
            }
        },"C").start();
 ​
    }
 }
 ​
 //资源类OOP
 class Ticket{
     //属性,方法
     private int number = 30;
 ​
     //卖票的方式
     //synchronized 本质:队列 锁
     public synchronized void sale(){
         if (number>0){
             System.out.println(Thread.currentThread().getName()+"卖出了第"+(number--)+"票,剩余"+number);
        }
    }
     //锁 锁的是对象
     //锁class
 ​
 }

公平锁:十分公平:可以先来后到(即排队)

非公平锁:十分公平:可以插队(默认)

 package com.kuang.demo06;
 ​
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantLock;
 ​
 public class SaleTicketDemo02 {
     public static void main(String[] args) {
         //并发:多线程操作同一个资源类,把资源丢入线程
         Ticket2 ticket = new Ticket2();
         //@FunctionalInterface 函数式接口,jdk1.8后 lambda表达式(参数)->{代码}
         new Thread(()->{ for (int i = 0; i < 40; i++) ticket.sale(); },"A").start();
         new Thread(()->{ for (int i = 0; i < 40; i++) ticket.sale(); },"B").start();
         new Thread(()->{ for (int i = 0; i < 40; i++) ticket.sale(); },"C").start();
 ​
    }
 }
 ​
 //Lock三部曲
 // 1.new ReentrantLock();
     //2.Lock.lock();//加锁
     //3.finally=> lock.unlock();//解锁
 ​
 class Ticket2{
     //属性,方法
     private int number = 30;
     Lock lock = new ReentrantLock();
 ​
     //卖票的方式
 ​
     public void sale(){
         lock.lock();//加锁
         try{
             //业务代码
             if (number>0){
                 System.out.println(Thread.currentThread().getName()+"卖出了第"+(number--)+"票,剩余"+number);
            }
 ​
 ​
        }catch (Exception e){
             e.printStackTrace();
        }finally{
             lock.unlock();//解锁
    }
 ​
    }
 ​
    }
 ​
 ​
 ​

Synchronized和Lock区别

1.Synchronized 是内置的java关键字,Lock是一个java类

2.Synchronized 无法判断获取的状态,Lock可以判断是否获取到了锁

3.Synchronized 会自动释放锁,loack必须要手动释放锁!如果不释放,会造成死锁

4.Synchronized 线程1(获得锁,阻塞)、线程2(等待,傻傻的等);Lock锁就不一定会等待下去。

5.Synchronized 可重入锁,不可以中断的,非公平;Lock,可重入锁,可以判断锁,非公平(可以自己设置);

6.Synchronized 适合锁少量的代码同步问题,Lock适合锁大量的同步代码!

4.生产者和消费者问题

面试的时候:单例模式 排序算法 生产者和消费者 死锁

Synchronized 版 wait notify

juc lock

生产者和消费者问题Synchronized 版

 package com.kuang.productorcous;
 /**
  *线程之间的通信问题:生产者和消费者问题!等待唤醒,通知唤醒
  * 线程交替执行 A B 操作同一个变量 num = 0
  * A num + 1
  * B num - 1
  */
 ​
 public class A {
     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;
 ​
     //+1
     //只要是并发编程一定要有锁
 ​
     public synchronized void increment() throws InterruptedException {
         if (number!=0){//0的时候干活
             //等待操作
             this.wait();
 ​
        }
         number++;
         System.out.println(Thread.currentThread().getName()+"=>"+number);
         //通知其他线程,我+1完毕了
         this.notifyAll();
    }
     public synchronized void decrement() throws InterruptedException {
         if (number==0){//1的时候干活
             //等待
             this.wait();
 ​
        }number--;
         System.out.println(Thread.currentThread().getName()+"=>"+number);
         //通知其他线程,我-1完毕了
         this.notifyAll();
    }
 }

问题存在:A B C D4个线程!存在虚假唤醒

if改为while判断

 package com.kuang.productorcous;
 /**
  *线程之间的通信问题:生产者和消费者问题!等待唤醒,通知唤醒
  * 线程交替执行 A B 操作同一个变量 num = 0
  * A num + 1
  * B num - 1
  */
 ​
 public class A {
     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();
         new Thread(()->{
             for (int i = 0; i < 10; i++)
                 try {
                     data.increment();
                } catch (InterruptedException e) {
                     e.printStackTrace();
                }
 ​
        },"C").start();
         new Thread(()->{
             for (int i = 0; i < 10; i++)
                 try {
                     data.decrement();
                } catch (InterruptedException e) {
                     e.printStackTrace();
                }
 ​
        },"D").start();
            }
 ​
 ​
 ​
 ​
    }
 ​
 ​
 ​
 //判断等待   业务   通知
 class Data{
     //数字 资源类是独立耦合的
     private  int number = 0;
 ​
     //+1
     //只要是并发编程一定要有锁
 ​
     public synchronized void increment() throws InterruptedException {
         while (number!=0){//0的时候干活
             //等待操作
             this.wait();
 ​
        }
         number++;
         System.out.println(Thread.currentThread().getName()+"=>"+number);
         //通知其他线程,我+1完毕了
         this.notifyAll();
    }
     public synchronized void decrement() throws InterruptedException {
         while (number==0){//1的时候干活
             //等待
             this.wait();
 ​
        }number--;
         System.out.println(Thread.currentThread().getName()+"=>"+number);
         //通知其他线程,我-1完毕了
         this.notifyAll();
    }
 }

JUC版的生产者与消费者

通过Lock找到Condition

代码实现:

 package com.kuang.productorcous;
 ​
 import java.util.concurrent.locks.Condition;
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantLock;
 ​
 public class B {
     public static void main(String[] args) {
         //创建一个资源类
         Data2 data = new Data2();
         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();
         new Thread(()->{
             for (int i = 0; i < 10; i++)
                 try {
                     data.increment();
                } catch (InterruptedException e) {
                     e.printStackTrace();
                }
 ​
        },"C").start();
         new Thread(()->{
             for (int i = 0; i < 10; i++)
                 try {
                     data.decrement();
                } catch (InterruptedException e) {
                     e.printStackTrace();
                }
 ​
        },"D").start();
    }
 ​
 ​
    }
 ​
     //判断等待   业务   通知
     class Data2 {
         //数字 资源类是独立耦合的
         private int number = 0;
         Lock lock = new ReentrantLock();
         Condition condition = lock.newCondition();
         // condition.await();//等待
         //condition.signalAll();//唤醒全部
 ​
         //+1
         //只要是并发编程一定要有锁
 ​
         public void increment() throws InterruptedException {
             lock.lock();
             try {
                 while (number != 0) {
                     //0的时候干活
                     condition.await();
                }
                 number++;
                 System.out.println(Thread.currentThread().getName() + "=>" + number);
                 //通知其他线程,我-1完毕了
                condition.signalAll();
            } catch (Exception e) {
                 e.printStackTrace();
            } finally {
                 lock.unlock();
 ​
            }
 ​
        }
 ​
 ​
         public synchronized void decrement() throws InterruptedException {
             lock.lock();
             try{
                 while (number == 0) {//1的时候干活
                     //等待
                     condition.await();
 ​
 ​
                }
                 number--;
                 System.out.println(Thread.currentThread().getName() + "=>" + number);
                 //通知其他线程,我-1完毕了
                 condition.signalAll();
 ​
            }catch (Exception e){
                 e.printStackTrace();
            }finally {
                 lock.unlock();
        }
 ​
        }
    }
 ​

任何一个新的技术,绝对不是仅仅只是覆盖了原来的技术,一定有其优势和补充!

Condition 精准的通知和唤醒线程

代码测试:

 package com.kuang.productorcous;
 ​
 import java.util.concurrent.locks.Condition;
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantLock;
 ​
 /**
  *A执行完调用B,B执行完调用C,C执行完调用A
  */
 ​
 public class C {
     public static void main(String[] args) {
         Data3 data = new Data3();
         new Thread(()->{
             for (int i = 0; i < 10; i++) {
                 data.printA();
            }
        },"A").start();
         new Thread(()->{
             for (int i = 0; i < 10; i++) {
                 data.printB();
            }
        },"B").start();
         new Thread(()->{
             for (int i = 0; i < 10; i++) {
                 data.printC();
            }
        },"C").start();
    }
 }
 class  Data3{
     //资源类Lock
     private Lock lock = new ReentrantLock();
     private Condition condition1 = lock.newCondition();
     private Condition condition2 = lock.newCondition();
     private Condition condition3 = lock.newCondition();
     private int number = 1;//为1时 A执行   为2时B执行 为3时 C执行
     public void printA(){
         lock.lock();
         try {
            //业务,判断->执行->通知
             while (number!=1){
                 //等待
                 condition1.await();
            }
             System.out.println(Thread.currentThread().getName()+"=>AAAAA");
             //唤醒,唤醒指定的人B
             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()+"=>BBBBB");
             //唤醒,唤醒指定的人C
             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()+"=>CCCCC");
             //唤醒,唤醒指定的人C
             number = 1;
             condition1.signal();
        } catch (Exception e) {
             e.printStackTrace();
        } finally {
             lock.unlock();
        }
 ​
 ​
    }
 ​
 ​
 ​
 }

快捷键模式:

ctrl alt+t :try catch的快捷键

或者在菜单栏中点击Code

5 如何判断锁是谁(8锁现象)

*深刻理解锁

对象、Class

 package com.kuang.lock8;
 ​
 import java.util.concurrent.TimeUnit;
 ​
 /**
  * 8锁,就是关于锁的8个问题
  *1.标准情况下。两个线程先是发短信 然后是打电话
  * 2.sendSms延迟四秒,两个线程先打印发短信还是先打印打电话 ?   先打印发短信 然后是打电话
  */
 ​
 public class Test1 {
     public static void main(String[] args) throws InterruptedException {
         Phone phone = new Phone();
 ​
         //phone.sendSms(); 锁的问题
 ​
         new Thread(()->{
             phone.sendSms();
        },"A").start();
 ​
         //捕获
 ​
         try {
             TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
             e.printStackTrace();
        }
         new Thread(()->{
             phone.call();
        },"B").start();
 ​
    }
 }
 class Phone{
     //synchronized 锁的对象是方法的调用者 phone是锁
     //两个方法(sendSms call)用的是同一个锁,谁先拿到谁执行
     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.kuang.lock8;
 ​
 import java.util.concurrent.TimeUnit;
 ​
 /**
  * 3.增加了一个普通方法后 程序是先执行发短息还是hello? 先输出hello 因为它是普通方法没有锁
  * 4.两个对象两个同步方法,是先发短息还是打电话?   //先打电话 然后是发短信 这个是按时间来
  */
 public class Test2 {
     public static void main(String[] args) throws InterruptedException {
        //两个对象,两个调用者 两把锁
         Phone2 phone1 = new Phone2();
         Phone2 phone2 = new Phone2();
 ​
         //phone.sendSms(); 锁的问题
 ​
         new Thread(()->{
             phone1.sendSms();
        },"A").start();
 ​
         //捕获
 ​
         try {
             TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
             e.printStackTrace();
        }
         new Thread(()->{
             phone2.call();
        },"B").start();
 ​
    }
 }
 class Phone2{
     //synchronized 锁的对象是方法的调用者 phone是锁
     //两个方法(sendSms call)用的是同一个锁,谁先拿到谁执行
     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.kuang.lock8;
 ​
 import java.util.concurrent.TimeUnit;
 ​
 /**
  * 5增加两个静态的同步方法,只有一个对象,是先打印发短息还是先打印打电话?//先发短息后打电话
  * 6.两个对象!增加两个静态的同步方法,是先发短息还是先打电话?//先发短息后打电话
  */
 public class Test3 {
     public static void main(String[] args) throws InterruptedException {
         //两个对象的Class类模板只有一个在加了static,锁的是Class
         Phone3 phone1 = new Phone3();
         Phone3 phone2 = new Phone3();
 ​
 ​
         //phone.sendSms(); 锁的问题
 ​
         new Thread(()->{
             phone1.sendSms();
        },"A").start();
 ​
         //捕获
 ​
         try {
             TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
             e.printStackTrace();
        }
         new Thread(()->{
             phone2.call();
        },"B").start();
 ​
    }
 }
 //Phone3只有唯一的一个Class对象
 // Class<Phone3> phone3Class = Phone3.class; 是全局唯一
 //static走的是class对象 锁的是Class
 class Phone3{
     //synchronized 锁的对象是方法的调用者 phone是锁
     //两个方法(sendSms call)用的是同一个锁,谁先拿到谁执行
     //static静态方法 类一加载就有了 锁的是 Class 模板
     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.kuang.lock8;
 ​
 import java.util.concurrent.TimeUnit;
 ​
 /**
  * 1.一个静态的同步方法 一个普通的同步方法 只有一个对象 先打印发短息还是先打印打电话??//先打电话后发短息 因为锁的对象不同
  *2.一个静态的同步方法 一个普通的同步方法 两个对象 先打印发短息还是先打印打电话??//先打电话后发短息
  */
 public class Test4 {
     public static void main(String[] args) throws InterruptedException {
         //两个对象的Class类模板只有一个在加了static,锁的是Class
         Phone4 phone1 = new Phone4();
         Phone4 phone2 = new Phone4();
 ​
 ​
 ​
         //phone.sendSms(); 锁的问题
 ​
         new Thread(()->{
             phone1.sendSms();
        },"A").start();
 ​
         //捕获
 ​
         try {
             TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
             e.printStackTrace();
        }
         new Thread(()->{
             phone2.call();
        },"B").start();
 ​
    }
 }
 //Phone3只有唯一的一个Class对象
 // Class<Phone3> phone3Class = Phone3.class; 是全局唯一
 //static走的是class对象 锁的是Class
 class Phone4{
     //静态的同步方法 锁的是Class类模板
     public static synchronized void sendSms(){
         try {
             TimeUnit.SECONDS.sleep(4);
        } catch (InterruptedException e) {
             e.printStackTrace();
        }
         System.out.println("发短信");
 ​
 ​
    }
     //普通的同步方法 锁的是调用者
     public static void call(){
         System.out.println("打电话");
 ​
    }
 ​
 ​
 ​
 }
 ​

小结

new this 具体的一个手机

static Class 唯一的一个模板

6 集合类不安全

List不安全

 package com.kuang.unsafe;
 ​
 import java.util.*;
 import java.util.concurrent.CopyOnWriteArrayList;
 ​
 //java.util.ConcurrentModificationException 并发修改异常
 public class ListTest {
     public static void main(String[] args) {
         //并发下 ArrayList不安全 Synchronized
         /**
          * 解决方案
          * 1.List<String> list = new Vector<>();
          * 2. List<String> list = Collections.synchronizedList(new ArrayList<>());
          * 3.List<String> list = new CopyOnWriteArrayList<>();
          * CopyOnWriteArrayList 写入时复制 COW 计算机程序设计领域的一种优化策略
          * 多个线程调用的时候,list是唯一的 读取的时候读取的是固定的,写入的时候可能存在后面写入的把前面的覆盖了
          * CopyOnWriteArrayList 是在写入的时候避免覆盖,造成数据问题
          *
          * 读写分离
          * CopyOnWriteArrayList比Vector的优点在哪?
          */
         
         List<String> list = new CopyOnWriteArrayList<>();
         for(int i = 1;i <=10;i++ ){
             new Thread(()->{
                 list.add(UUID.randomUUID().toString().substring(0,5));
                 System.out.println(list);
            },String.valueOf(i)).start();
 ​
        }
    }
 }
 ​

第44天学习打卡(JUC 线程和进程 并发和并行 Lock锁 生产者和消费者问题 如何判断锁(8锁问题) 集合类不安全)的更多相关文章

  1. 【java线程系列】java线程系列之线程间的交互wait()/notify()/notifyAll()及生产者与消费者模型

    关于线程,博主写过java线程详解基本上把java线程的基础知识都讲解到位了,但是那还远远不够,多线程的存在就是为了让多个线程去协作来完成某一具体任务,比如生产者与消费者模型,因此了解线程间的协作是非 ...

  2. python之线程和进程(并发编程)

    python的GIL In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple native ...

  3. Python 线程(threading) 进程(multiprocessing)

    *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !important; } /* ...

  4. 图解并发与并行-分别从CPU和线程的角度理解

    本文作为图解java并发编程的第三篇,前2篇访问地址如下所示: 图解进程线程.互斥锁与信号量-看完还不懂你来打我 8成以上的java线程状态图都画错了--图解java并发第二篇 一.CPU角度的并发与 ...

  5. Java 线程的通讯--生产者和消费者

    package 生产者和消费者; //消费者 public class Customer implements Runnable { private Share_resources rescource ...

  6. 第41天学习打卡(死锁 Lock synchronized与Lock的对比 线程协作 使用线程池)

    死锁 多个线程各自占有一些共享资源,并且互相等待其他线程占有的资源才能运行,而导致两个或者多个线程都在等待对方释放资源,都停止执行的情形.某一个同步块同时拥有"两个以上对象的锁"时 ...

  7. 学习笔记 07 --- JUC集合

    学习笔记 07 --- JUC集合 在讲JUC集合之前我们先总结一下Java的集合框架,主要包含Collection集合和Map类.Collection集合又能够划分为LIst和Set. 1. Lis ...

  8. python学习笔记12 ----线程、进程

    进程和线程的概念 进程和线程是操作系统中两个很重要的概念,对于一般的程序,可能有若干个进程,每一个进程有若干个同时执行的线程.进程是资源管理的最小单位,线程是程序执行的最小单位(线程可共享同一进程里的 ...

  9. Java核心知识点学习----使用Condition控制线程通信

    一.需求 实现线程间的通信,主线程循环3次后,子线程2循环2次,子线程3循环3次,然后主线程接着循环3次,如此循环3次. 即:A->B->C---A->B->C---A-> ...

随机推荐

  1. linux(2)系统目录结构

    前言 平常linux系统用的也不少,那么linux下的每个目录都是用来干什么的,小伙伴们有仔细研究过吗?让我们来了解下吧 Linux 系统目录结构 登录系统后,在当前命令窗口下输入命令: [root@ ...

  2. 2020Nowcode多校 Round5 C. Easy

    C. Easy 构造两个序列分别要满足 \(\sum_{i=1}^{k} a_{i} = N\) \(\sum_{i=1}^{k} b_{i} = M\) 一种方案能贡献\(\prod_{i=1}^{ ...

  3. hdu5643 King's Game(约瑟夫环+线段树)

    Problem Description In order to remember history, King plans to play losephus problem in the parade ...

  4. 【uva 12174】Shuffle(算法效率--滑动窗口)

    题意:假设一种音乐播放器有一个乱序的功能,设定每播放S首歌为一个周期,随机播放编号为1~S的歌曲.现在给一个长度为N的部分播放记录,请统计下次随机排序所发生的时间的可能性种数.(1≤S,N≤10000 ...

  5. P1280 尼克的任务(DP)

    题目描述 尼克每天上班之前都连接上英特网,接收他的上司发来的邮件,这些邮件包含了尼克主管的部门当天要完成的全部任务,每个任务由一个开始时刻与一个持续时间构成. 尼克的一个工作日为N分钟,从第一分钟开始 ...

  6. java调用http接口的几种方式总结

    本文参考: https://blog.csdn.net/fightingXia/article/details/71775516 https://www.cnblogs.com/jeffen/p/69 ...

  7. leetcode 36 有效的数独 哈希表 unordered_set unordersd_map 保存状态 leetcode 37 解数独

    leetcode 36 感觉就是遍历. 保存好状态,就是各行各列还有各分区divide的情况 用数组做. 空间小时间大 class Solution { public: bool isValidSud ...

  8. c++ cin 读入txt的问题

    源程序 #include <iostream> using namespace std; struct Stack { int tos; int stackarray[1000]; }; ...

  9. In_array()函数弱比较

    0x01 定义 (PHP 4, PHP 5, PHP 7) in_array - 检查数组中是否存在某个值 说明 in_array ( mixed $needle , array $haystack ...

  10. Generator function vs Async/Await

    Generator function vs Async/Await generator async /await refs xgqfrms 2012-2020 www.cnblogs.com 发布文章 ...