JUC(java.util.concurrent)

1.可重入锁多线程售票案例

package com.test.concurrent;import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;/*** 可重入锁多线程售票案例*/
public class SaleTicketDemo01 {public static void main(String[] args) {Ticket ticket = new Ticket();
//        new Thread(new Runnable() {//            @Override
//            public void run() {//                //不要轻易写while(true)死循环
//                for (int i = 0; i <40 ; i++) {//                    ticket.sale();
//                }
//            }
//        },"A").start();
//        new Thread(new Runnable() {//            @Override
//            public void run() {//                //不要轻易写while(true)死循环
//                for (int i = 0; i <40 ; i++) {//                    ticket.sale();
//                }
//            }
//        },"B").start();
//        new Thread(new Runnable() {//            @Override
//            public void run() {//                //不要轻易写while(true)死循环
//                for (int i = 0; i <40 ; i++) {//                    ticket.sale();
//                }
//            }
//        },"C").start();//对于参数含有匿名内部类的可以用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();}
}class Ticket{private int number = 30;Lock lock = new ReentrantLock();//同步方法或同步代码块 这里用可重入锁public void sale(){lock.lock();try{if(number>0){System.out.println(Thread.currentThread().getName()+"\t卖出第"+(number--)+"张票\t还剩下:"+number);}}catch (Exception e){e.printStackTrace();}finally {lock.unlock();}}
}

2、Java8新特性 lambda表达式

package com.test.concurrent;/*** Java8新特性 lambda表达式*/
public class LambdaExpressDemo01 {public static void main(String[] args) {//        Foo foo = new Foo() {//            @Override
//            public void sayHello() {//                System.out.println("hello,zhangsan!");
//            }
//        };
//        foo.sayHello();Foo foo = ()->{System.out.println("hello,zhangsan!");};foo.sayHello();Foo1 foo1 = (int x,int y)->{System.out.println("come in add method");return x+y;};System.out.println(foo1.add(3,5));System.out.println(foo1.mul(3,6));}
}interface  Foo{public void sayHello();//只允许一个函数?
}
@FunctionalInterface //保证是一个函数式接口  java8 允许接口部分实现
interface Foo1{public int add(int x,int y);//default 只允许定义一个default int mul(int x,int y){return x * y;}public static int div(int x,int y){return x/y;}public static int div2(int x,int y){return x/y;}
}

3、集合类不安全

package com.test.concurrent;import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;/*** Java并发编程集合类不安全* ArrayList 、HashSet、HashMap都是不安全的* 解决办法* List<String> list = new Vector<>();* List<String> list = Collections.synchronizedList(new ArrayList<>());* List<String> list = new CopyOnWriteArrayList<>();*/
public class UnSafeDemo01 {public static void main(String[] args) {//ArrayList线程不安全
//        List<String> list = new ArrayList<>();//解决办法
//        List<String> list = new Vector<>();
//        List<String> list = Collections.synchronizedList(new ArrayList<>());List<String> list = new CopyOnWriteArrayList<>();
//        list.add("A");
//        list.add("B");
//        list.add("C");
//        list.forEach(System.out::println); //消费型函数for (int i = 1; i <=30 ; i++) {new Thread(()->{list.add(UUID.randomUUID().toString().substring(0,8));System.out.println(list);},String.valueOf(i)).start();}}
}

4、八锁演示及解释

package com.test.concurrent;import java.util.concurrent.TimeUnit;/*** 八锁问题,先打印邮件还是短信?* 1.标准访问* **********send Email* **********send SMS* 2.邮件暂停4s* **********send Email* **********send SMS* 3.新增普通方法sayHello(),先打印邮件还是sayHello* **********sayHello* **********send Email* 4.两部手机* **********send SMS* **********send Email* 5.两个静态同步方法* **********send Email* **********send SMS* 6.两个静态同步方法,两部手机* **********send Email* **********send SMS* 7.1个静态同步方法,一个普通方法,同一部手机* **********sayHello* **********send Email* 8.1.个静态同步方法,一个普通方法,两部手机* **********sayHello* **********send Email*/
public class Lock8Demo01 {public static void main(String[] args) throws InterruptedException{Phone phone = new Phone();Phone phone1 = new Phone();//线程的调度不是顺序的,与系统和cpu有关new Thread(()->{try {phone.sendEmail();} catch (Exception e) {e.printStackTrace();}},"A").start();Thread.sleep(100);new Thread(()->{try {phone.sayHello();
//                phone.sayHello();
//                phone1.sendSMS();} catch (Exception e) {e.printStackTrace();}},"B").start();}
}class Phone{public static synchronized void sendEmail()throws Exception{TimeUnit.SECONDS.sleep(4);System.out.println("**********send Email");}public static synchronized void sendSMS()throws Exception{System.out.println("**********send SMS");}public void sayHello(){System.out.println("**********sayHello");}
}

1.标准访问 先打印Email还是SMS?

package test.testThread.juc;
/*** @author *cruder* @version 1.0* @since 2021/1/17 11:01*/
public class Lock8Demo01 {public static void main(String[] args) throws InterruptedException{Phone phone = new Phone();//线程的调度不是顺序的,与系统和cpu有关new Thread(()->{try {phone.sendEmail();} catch (Exception e) {e.printStackTrace();}},"A").start();Thread.sleep(100);new Thread(()->{try {phone.sendSMS();} catch (Exception e) {e.printStackTrace();}},"B").start();}
}class Phone{public synchronized void sendEmail()throws Exception{System.out.println("**********send Email");}public synchronized void sendSMS(){System.out.println("**********send SMS");}
}

解释:主线程顺序执行,沉睡了100ms,线程A先启动访问资源,所以先打印的Email。如果不成睡,两个线程启动不存在顺序关系,哪个线程先启动跟操作系统和cpu的状态有关。

2.邮件暂停4s 先打印Email还是SMS?

package test.testThread.juc;import java.util.concurrent.TimeUnit;/*** @author *cruder* @version 1.0* @since 2021/1/17 11:01*/
public class Lock8Demo01 {public static void main(String[] args) throws InterruptedException{Phone phone = new Phone();//线程的调度不是顺序的,与系统和cpu有关new Thread(()->{try {phone.sendEmail();} catch (Exception e) {e.printStackTrace();}},"A").start();Thread.sleep(100);new Thread(()->{try {phone.sendSMS();} catch (Exception e) {e.printStackTrace();}},"B").start();}
}class Phone{public synchronized void sendEmail()throws Exception{TimeUnit.SECONDS.sleep(4);System.out.println("**********send Email");}public synchronized void sendSMS(){System.out.println("**********send SMS");}
}
**********send Email
**********send SMS

解释:synchronized 修饰方法锁住的是当前对象this,因此当A进入到同步方法后,B只有等A访问完后才能访问。

3.新增普通方法sayHello(),先打印邮件还是sayHello

package test.testThread.juc;import java.util.concurrent.TimeUnit;/*** @author *cruder* @version 1.0* @since 2021/1/17 11:01*/
public class Lock8Demo01 {public static void main(String[] args) throws InterruptedException{Phone phone = new Phone();//线程的调度不是顺序的,与系统和cpu有关new Thread(()->{try {phone.sendEmail();} catch (Exception e) {e.printStackTrace();}},"A").start();Thread.sleep(100);new Thread(()->{try {//                phone.sendSMS();phone.sayHello();} catch (Exception e) {e.printStackTrace();}},"B").start();}
}class Phone{public synchronized void sendEmail()throws Exception{TimeUnit.SECONDS.sleep(4);System.out.println("**********send Email");}public synchronized void sendSMS(){System.out.println("**********send SMS");}public void sayHello(){System.out.println("say Hello");}
}
say Hello
**********send Email

解释:普通方法跟同步锁无关,锁的是整个对象的同步方法

4.两部手机,一个手机发邮件一个手机发短信,先打印Emai还是SMS

package test.testThread.juc;import java.util.concurrent.TimeUnit;/*** @author *cruder* @version 1.0* @since 2021/1/17 11:01*/
public class Lock8Demo01 {public static void main(String[] args) throws InterruptedException{Phone phone = new Phone();Phone phone1 = new Phone();//线程的调度不是顺序的,与系统和cpu有关new Thread(()->{try {phone.sendEmail();} catch (Exception e) {e.printStackTrace();}},"A").start();Thread.sleep(100);new Thread(()->{try {phone1.sendSMS();
//                phone.sayHello();} catch (Exception e) {e.printStackTrace();}},"B").start();}
}class Phone{public synchronized void sendEmail()throws Exception{TimeUnit.SECONDS.sleep(4);System.out.println("**********send Email");}public synchronized void sendSMS(){System.out.println("**********send SMS");}public void sayHello(){System.out.println("say Hello");}
}
**********send SMS
**********send Email

解释:两部手机已经是两把锁了,不存在资源争夺现象,第二部手机没有等4s所以先打印出SMS

5.两个静态同步方法,同一部手机,先打印Email还是SMS?

package test.testThread.juc;import java.util.concurrent.TimeUnit;/*** @author *cruder* @version 1.0* @since 2021/1/17 11:01*/
public class Lock8Demo01 {public static void main(String[] args) throws InterruptedException{Phone phone = new Phone();Phone phone1 = new Phone();//线程的调度不是顺序的,与系统和cpu有关new Thread(()->{try {phone.sendEmail();} catch (Exception e) {e.printStackTrace();}},"A").start();Thread.sleep(100);new Thread(()->{try {phone.sendSMS();
//                phone.sayHello();} catch (Exception e) {e.printStackTrace();}},"B").start();}
}class Phone{public static synchronized void sendEmail()throws Exception{TimeUnit.SECONDS.sleep(4);System.out.println("**********send Email");}public static synchronized void sendSMS(){System.out.println("**********send SMS");}public void sayHello(){System.out.println("say Hello");}
}
**********send Email
**********send SMS

解释: synchronized是实现同步的基础,java中的每一个对象都可以作为锁
具体表现为以下三种形式:
1.对于普通同步方法,锁的是当前对象
2.对于同步代码块,锁的是synchronized 括号里配置的对象
3.对于静态同步方法,锁的是当前类的Class对象。

6.两个静态同步方法,两部手机,先打印Email还是SMS?

package test.testThread.juc;import java.util.concurrent.TimeUnit;/*** @author *cruder* @version 1.0* @since 2021/1/17 11:01*/
public class Lock8Demo01 {public static void main(String[] args) throws InterruptedException{Phone phone = new Phone();Phone phone1 = new Phone();//线程的调度不是顺序的,与系统和cpu有关new Thread(()->{try {phone.sendEmail();} catch (Exception e) {e.printStackTrace();}},"A").start();Thread.sleep(100);new Thread(()->{try {phone1.sendSMS();
//                phone.sayHello();} catch (Exception e) {e.printStackTrace();}},"B").start();}
}class Phone{public static synchronized void sendEmail()throws Exception{TimeUnit.SECONDS.sleep(4);System.out.println("**********send Email");}public static synchronized void sendSMS(){System.out.println("**********send SMS");}public void sayHello(){System.out.println("say Hello");}
}
**********send Email
**********send SMS

解释: synchronized是实现同步的基础,java中的每一个对象都可以作为锁
具体表现为以下三种形式:
1.对于普通同步方法,锁的是当前对象
2.对于同步代码块,锁的是synchronized 括号里配置的对象
3.对于静态同步方法,锁的是当前类的Class对象。
7.一个静态同步方法,一个普通同步方法,一部手机,先打印Email还是SMS?

package test.testThread.juc;import java.util.concurrent.TimeUnit;/*** @author *cruder* @version 1.0* @since 2021/1/17 11:01*/
public class Lock8Demo01 {public static void main(String[] args) throws InterruptedException{Phone phone = new Phone();Phone phone1 = new Phone();//线程的调度不是顺序的,与系统和cpu有关new Thread(()->{try {phone.sendEmail();} catch (Exception e) {e.printStackTrace();}},"A").start();Thread.sleep(100);new Thread(()->{try {phone.sendSMS();
//                phone1.sayHello();} catch (Exception e) {e.printStackTrace();}},"B").start();}
}class Phone{public static synchronized void sendEmail()throws Exception{TimeUnit.SECONDS.sleep(4);System.out.println("**********send Email");}public synchronized void sendSMS(){System.out.println("**********send SMS");}public void sayHello(){System.out.println("say Hello");}
}
**********send SMS
**********send Email

解释:当一个线程试图访问同步代码块时,它首先必须得到锁,退出或抛出异常时必须释放锁。也就是说如果一个实例对象的非静态同步方法获取锁后,该实例对象的其他非静态同步方法必须等待获取锁的方法释放锁后才能获取锁,可是别的实力对象的非静态同步方法因为跟该实例对象的非静态同步方法用的是不同的锁,所以不用等待该实例对象已获取的锁的非静态同步方法释放锁就可以获取他们自己的锁。

所有的静态同步方法用的也是同一把锁——类对象本身,这两把锁是两个不同的对象,所以静态同步方法与非静态同步方法之间不存在竞争。但是一旦一个静态同步方法获取锁后,其他的静态同步方法都必须等待该方法释放锁后才能获取锁,而不管是否是同一个实例对象还是不同的实例对象。

8.一个静态同步方法,一个普通同步方法,两部手机,先打印Email还是SMS?

package test.testThread.juc;import java.util.concurrent.TimeUnit;/*** @author *cruder* @version 1.0* @since 2021/1/17 11:01*/
public class Lock8Demo01 {public static void main(String[] args) throws InterruptedException{Phone phone = new Phone();Phone phone1 = new Phone();//线程的调度不是顺序的,与系统和cpu有关new Thread(()->{try {phone.sendEmail();} catch (Exception e) {e.printStackTrace();}},"A").start();Thread.sleep(100);new Thread(()->{try {phone1.sendSMS();
//                phone1.sayHello();} catch (Exception e) {e.printStackTrace();}},"B").start();}
}class Phone{public static synchronized void sendEmail()throws Exception{TimeUnit.SECONDS.sleep(4);System.out.println("**********send Email");}public synchronized void sendSMS(){System.out.println("**********send SMS");}public void sayHello(){System.out.println("say Hello");}
}
**********send SMS
**********send Email

解释:当一个线程试图访问同步代码块时,它首先必须得到锁,退出或抛出异常时必须释放锁。也就是说如果一个实例对象的非静态同步方法获取锁后,该实例对象的其他非静态同步方法必须等待获取锁的方法释放锁后才能获取锁,可是别的实力对象的非静态同步方法因为跟该实例对象的非静态同步方法用的是不同的锁,所以不用等待该实例对象已获取的锁的非静态同步方法释放锁就可以获取他们自己的锁。

所有的静态同步方法用的也是同一把锁——类对象本身,这两把锁是两个不同的对象,所以静态同步方法与非静态同步方法之间不存在竞争。但是一旦一个静态同步方法获取锁后,其他的静态同步方法都必须等待该方法释放锁后才能获取锁,而不管是否是同一个实例对象还是不同的实例对象。

参考网站https://www.bilibili.com/video/BV1vE411D7KE

JUC与JVM并发编程学习笔记01相关推荐

  1. 基于《狂神说Java》JUC并发编程--学习笔记

    前言: 本笔记仅做学习与复习使用,不存在刻意抄袭. -------------------------------------------------------------------------- ...

  2. 【并发入门】Java 并发编程学习笔记

    注:该笔记主要记录自 B站 up主 遇见狂神说的个人空间_哔哩哔哩_bilibili 1.什么是 JUC Java 工具类中的 并发编程包 学习:源码 + 官方文档 业务:普通的线程代码 Thread ...

  3. 网易云课堂微专业--Java高级开发工程师--多线程并发编程--学习笔记(二)

    文章目录 第一章 多线程并发编程 第二节 线程安全问题 1.2.1 线程安全之可见性问题 多线程中的问题 从内存结构到内存模型 工作内存缓存 指令重排序 内存模型的含义 Shared Variable ...

  4. Java并发编程学习笔记(二)多线程的理解及多线程的优点

    多线程的优点 原文:http://tutorials.jenkov.com/java-concurrency/benefits.html 作者:Jakob Jenkov        翻译:古圣昌   ...

  5. Java并发编程学习笔记——volatile与synchronized关键字原理及使用

    Java代码在编译后会变成Java字节码,字节码被类加载器加载到JVM里,JVM执行字节码,最终需要转化为汇编指令在CPU上执行,Java中所使用的并发机制依赖于JVM的实现和CPU的指令. 一.vo ...

  6. JAVA并发编程学习笔记之CAS操作

    http://blog.csdn.net/aesop_wubo/article/details/7537960 CAS操作 CAS是单词compare and set的缩写,意思是指在set之前先比较 ...

  7. Python微信打飞机游戏编程学习笔记01

    刚学习Python,看别人写的小游戏,照搬照学照写,纯手工手打,一步步,加深印象,加深学习 运行环境是: Python 3.7.1   pygame 1.9.4 微信很火的打飞机游戏拿了学习下 第一步 ...

  8. JAVA并发编程学习笔记------FutureTask

    FutureTask是Future和Callable的结合体.传统的代码是这样写的 Future f = executor.submit(new Callable()); 然后通过Future来取得计 ...

  9. 张孝祥并发编程学习笔记实践

    1.要用到共同数据(包括同步锁)的若干个方法应该归在同一个类身上,这种设计正好体现了高类聚和程序的健壮性 2.在迭代集合的过程中不能对集合进行修改 转载于:https://www.cnblogs.co ...

  10. windows网络编程--学习笔记01

    1. Winsock system architecture 2. 各种类型的protocol (1)Message-Oriented面向消息的协议 特点:保留数据边界,即每一条消息是界限分明的,一条 ...

最新文章

  1. linux 程序自启
  2. 数学图形(1.32) 鸡蛋
  3. SaltStack工具中MySQL的模块返回值问题解决
  4. 【集合框架】JDK1.8源码分析之IdentityHashMap(四)
  5. java堆算法,Java 基本功04-JVM-Java堆详解和GC算法
  6. 算法导论——动态规划:0-1背包问题(完全解)
  7. pyecharts地图使用
  8. 嘉年华ON LINE首次在墨天轮和视频号并机直播,数据库内核技术抢先get
  9. 暴跌343亿,被吐槽太土!中国最惨的老品牌,还有救吗?
  10. 电子科技大学计算机2019报名人数,电子科技大学录取分数线2019(在各省市录取数据)...
  11. 谷歌开源 VR 应用
  12. 迈向 HTTPS,HTTPS 到底解决了什么问题
  13. Linux复习-vi编辑器
  14. 区块链 fisco bcos webase-front docker方式部署
  15. 如何去除list中的重复元素
  16. csv用excel打开后乱码的解决方法
  17. 【阅读笔记】Implementation of tactical maneuvers with maneuver libraries
  18. 实验室gpu服务器集群 使用方法探索
  19. Maven入门教程(十七)-Maven多Moudle项目创建
  20. 写一篇关于乡愁的作文1000字以上

热门文章

  1. 玩玩AJAX之使用ashx文件响应来自JQuery的JSON请求.
  2. skimage io.imread
  3. 第四季-专题5-内核模块开发
  4. Kubernetes Job Controller源码分析
  5. 了解RxJava以及如何在Android应用中使用它
  6. 工具-WPT(Windows Performances Tool Kit) References
  7. TestNG官方文档中文版(1)-介绍
  8. Silverlight 4 tools
  9. C# 在采集数据时的验证与登录处理
  10. treeview 如何从多个数据表中获取数据动态生成 [提问]