什么是JUC

1.java.util工具包 包 分类

业务:普通的线程代码 Thread

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

2.线程和进程

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

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


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

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

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

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

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

并发 、并行

并发编程:并发 并行

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

并行(多个人一起行走)

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

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

<pre class="md-fences md-end-block md-fences-with-lineno ty-contain-cm modeLoaded"> package com.kuang.demo06;<br></br> ​<br></br> public class Test1 {<br></br>     public static void main(String[] args) {<br></br> ​<br></br>         //获取CPU的核数<br></br>         System.out.println(Runtime.getRuntime().availableProcessors());<br></br> ​<br></br> ​<br></br>     }<br></br> }<br></br> ​

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

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

1.来自不同的类

wait=>Object

sleep=>Thread

<pre class="md-fences md-end-block md-fences-with-lineno ty-contain-cm modeLoaded">  TimeUnit.DAYS.sleep(1);<br></br>  TimeUnit.SECONDS.sleep(2);

2关于锁的释放

wait会释放锁

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

3使用范围不同

wait:必须在同步代码块中

sleep:可以在任何地方

4 是否需要捕获异常

wait不需要捕获异常

sleep必须要捕获异常

3、Lock锁(重点)

传统synchronized

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

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

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

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

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

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

<pre class="md-fences md-end-block md-fences-with-lineno ty-contain-cm modeLoaded"> package com.kuang.demo06;<br></br> ​<br></br> import java.util.concurrent.locks.Lock;<br></br> import java.util.concurrent.locks.ReentrantLock;<br></br> ​<br></br> public class SaleTicketDemo02 {<br></br>     public static void main(String[] args) {<br></br>         //并发:多线程操作同一个资源类,把资源丢入线程<br></br>         Ticket2 ticket = new Ticket2();<br></br>         //@FunctionalInterface 函数式接口,jdk1.8后 lambda表达式(参数)->{代码}<br></br>         new Thread(()->{ for (int i = 0; i < 40; i++) ticket.sale(); },"A").start();<br></br>         new Thread(()->{ for (int i = 0; i < 40; i++) ticket.sale(); },"B").start();<br></br>         new Thread(()->{ for (int i = 0; i < 40; i++) ticket.sale(); },"C").start();<br></br> ​<br></br>     }<br></br> }<br></br> ​<br></br> //Lock三部曲<br></br> // 1.new ReentrantLock();<br></br>     //2.Lock.lock();//加锁<br></br>     //3.finally=> lock.unlock();//解锁<br></br> ​<br></br> class Ticket2{<br></br>     //属性,方法<br></br>     private int number = 30;<br></br>     Lock lock = new ReentrantLock();<br></br> ​<br></br>     //卖票的方式<br></br> ​<br></br>     public void sale(){<br></br>         lock.lock();//加锁<br></br>         try{<br></br>             //业务代码<br></br>             if (number>0){<br></br>                 System.out.println(Thread.currentThread().getName()+"卖出了第"+(number--)+"票,剩余"+number);<br></br>             }<br></br> ​<br></br> ​<br></br>         }catch (Exception e){<br></br>             e.printStackTrace();<br></br>         }finally{<br></br>             lock.unlock();//解锁<br></br>     }<br></br> ​<br></br>     }<br></br> ​<br></br>     }<br></br> ​<br></br> ​<br></br> ​
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 版
<pre class="md-fences md-end-block md-fences-with-lineno ty-contain-cm modeLoaded"> package com.kuang.productorcous;<br></br> /**<br></br>  *线程之间的通信问题:生产者和消费者问题!等待唤醒,通知唤醒<br></br>  * 线程交替执行 A B 操作同一个变量 num = 0<br></br>  * A num + 1<br></br>  * B num - 1<br></br>  */<br></br> ​<br></br> public class A {<br></br>     public static void main(String[] args) {<br></br>         //创建一个资源类<br></br>         Data data = new Data();<br></br>         new Thread(()->{<br></br>             for (int i = 0; i < 10; i++) {<br></br>                 try {<br></br>                     data.increment();<br></br>                 } catch (InterruptedException e) {<br></br>                     e.printStackTrace();<br></br>                 }<br></br> ​<br></br>             }<br></br> ​<br></br>         },"A").start();<br></br>         new Thread(()->{<br></br>             for (int i = 0; i < 10; i++)<br></br>                 try {<br></br>                     data.decrement();<br></br>                 } catch (InterruptedException e) {<br></br>                     e.printStackTrace();<br></br>                 }<br></br> ​<br></br>             },"B").start();<br></br>             }<br></br> ​<br></br> ​<br></br> ​<br></br> ​<br></br>     }<br></br> ​<br></br> ​<br></br> ​<br></br> //判断等待   业务   通知<br></br> class Data{<br></br>     //数字 资源类是独立耦合的<br></br>     private  int number = 0;<br></br> ​<br></br>     //+1<br></br>     //只要是并发编程一定要有锁<br></br> ​<br></br>     public synchronized void increment() throws InterruptedException {<br></br>         if (number!=0){//0的时候干活<br></br>             //等待操作<br></br>             this.wait();<br></br> ​<br></br>         }<br></br>         number++;<br></br>         System.out.println(Thread.currentThread().getName()+"=>"+number);<br></br>         //通知其他线程,我+1完毕了<br></br>         this.notifyAll();<br></br>     }<br></br>     public synchronized void decrement() throws InterruptedException {<br></br>         if (number==0){//1的时候干活<br></br>             //等待<br></br>             this.wait();<br></br> ​<br></br>         }number--;<br></br>         System.out.println(Thread.currentThread().getName()+"=>"+number);<br></br>         //通知其他线程,我-1完毕了<br></br>         this.notifyAll();<br></br>     }<br></br> }
问题存在:A B C D4个线程!存在虚假唤醒

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

if改为while判断

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

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

通过Lock找到Condition

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

代码实现:

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

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

Condition 精准的通知和唤醒线程

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

代码测试:

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

快捷键模式:

ctrl alt+t :try catch的快捷键

或者在菜单栏中点击Code

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

*深刻理解锁

对象、Class

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

new this 具体的一个手机

static Class 唯一的一个模板

6 集合类不安全

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

标签: 线程, void, number, Lock, Thread, JUC, 打卡, new, public

相关文章推荐

添加新评论,含*的栏目为必填