JUC基础笔记(尚硅谷周阳JUC的笔记)

概述

  • juc就是 java.util.concurrent包的首字母
  • 下面又分 并发包、 atomic 和 locks 包
  • 也就是所谓的并发工具类
  • 进程: 是程序的一次执行,拥有独立资源的单位
  • 线程:轻量级进程,共享进程中的内存资源 ,程序调度和分配的基本单位, 更好的使程序并发的执行
  • 并发: 是在程序在宏观上是并行, 实则是交替的执行
  • 并行: 两个程序一起执行,同步执行。
  • 在高内聚低耦合的前端下: 多线程编程的企业级套路 + 模板:
    * 线程 操作(对外暴露的调用方法) 资源类
    * 多线程操作共享资源
    * 先写共享资源类
    * 在写对共享资源的操作
    * 实现Runnable接口的匿名实现
    在这里插入图片描述
    在这里插入图片描述

卖票

//过去javase的写法
class Ticket{
   //资源类
    //票
    private int number = 30;

    public synchronized void saleTicket(){
   
        if (number > 0){
   
            System.out.println(Thread.currentThread().getName()+"\t卖出第:"+(number--)+"\t还剩下:"+number);
        }
    }
}
/**
 *题目:三个售票员   卖出   30张票
 * 多线程编程的企业级套路+模板
 * 1.在高内聚低耦合的前提下,线程    操作(对外暴露的调用方法)     资源类
 */
public class SaleTicket {
   
    public static void main(String[] args) {
   
        Ticket ticket = new Ticket();

        new Thread(new Runnable() {
   
            @Override
            public void run() {
   
                for (int i = 1; i <= 40; i++) {
   
                    ticket.saleTicket();
                }
            }
        },"A").start();

        new Thread(new Runnable() {
   
            @Override
            public void run() {
   
                for (int i = 1; i <= 40; i++) {
   
                    ticket.saleTicket();
                }
            }
        },"B").start();

        new Thread(new Runnable() {
   
            @Override
            public void run() {
   
                for (int i = 1; i <= 40; i++) {
   
                    ticket.saleTicket();
                }
            }
        },"C").start();
    }
}

在这里插入图片描述

//利用lock写法 lock相较于synchronized较为灵活, 而且锁的范围更少, 有点类似于操作系统的信号量
public class CurrentTicket {
   
    public static void main(String[] args) {
   

        Ticket ticket = new Ticket();

        new Thread(new Runnable() {
   
            @Override
            public void run() {
   
                for (int i = 0; i <= 40; i ++)
                  ticket.saleTicket();
            }
        }, "a").start();
        new Thread(new Runnable() {
   
            @Override
            public void run() {
   
                for (int i = 0; i <= 40; i ++)
                  ticket.saleTicket();
            }
        }, "b").start();

        //写成lamb表达式
        new Thread(()->{
   for (int i = 1; i <= 40; i++) ticket.sale();},"A").start();
        new Thread(()->{
   for (int i = 1; i <= 40; i++) ticket.sale();},"B").start();
        new Thread(()->{
   for (int i = 1; i <= 40; i++) ticket.sale();},"C").start();
    }
}
class Ticket{
   
    private int count = 50;
    private Lock lock = new ReentrantLock();
    public void saleTicket(){
   
        lock.lock();

        try {
   
            if (count > 0){
   
                System.out.println(Thread.currentThread().getName() + count);
                count --;
            }
        } finally {
   
            lock.unlock();
        }

    }
}

Lambda表达式

  • 对于一个接口来说如果只一个没有实现的方法可以直接用lambda表达式替换 (为什么说没有实现, 因为jdk8 接口中可以写默认实现, 以及静态方法)
  • 对于声明式函数接口 的注解@FunctionalInterface
  • 原则 拷贝中括号, 写死右箭头, 落地大括号
//什么意思呢
interface Foo{
   
      int div ();
}
//我们就可以这么做
Foo f = () -> {
   写实现;  return;};
f.div();即可
// 对于有返回值有参数的
 interface Foo{
   
      int div (int a, int b);
}
Foo f = (a, b) -> {
   写实现; return};
f.div(1, 2);就可以

线程间的通信

  • 一个进程内, 线程间的协调和调度, 操作共享资源。
  • 不同进程间的通信得利用操作系统中讲的进程通信。
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author xiaofei
 * @create 2021-07-28 9:53
 */


/*
 * 题目: 现在两个线程, 可以操作初始值位零的一个变量,
 * 实现一个进程对变量加一, 一个线程对改变量减一
 * 实现交替, 来10轮, 变量初始值为零
 *
 *
 * 1、高内聚低耦合, 线程操作资源类
 * 2、判断/干活/通知
 * 3、多线程交互中, 必须要防止多线程的续集唤醒, 也即 (判断使用while不
 * 能用if)
 * 4、标志位
 * 唤醒的时候还必须在判断
 * */

class AirConditioner {
   
    private int num = 0;
    private Lock lock = new ReentrantLock();

    public synchronized void add() throws InterruptedException {
   
          //这种情况会出错的原因是线程被唤醒的时侯就不需要在拍段一次条件了故在面对超过两个线程的时候就出现错误
//        if (num != 0) this.wait();
//        num ++;
//        System.out.println(Thread.currentThread().getName() + " " + num);
//
//        this.notifyAll();
        //第一种解决办法
        while (num != 0) this.wait();
        num ++;
        System.out.println(Thread.currentThread().getName() + " " + num);

        this.notifyAll();

        //第二种解决办法 说到底都是 让其唤醒的时候在经历一次判断 另外这样写可能打出来的结果可能不是40行
        // 因为被唤醒之后就不是去去执行本次的操作而是直接本次操作结束 执行 i++ 了
//        if (num == 0) {
   
//            num ++;
//            System.out.println(Thread.currentThread().getName() + " " + num);
//            this.notifyAll();
//        }else
//            this.wait();


    }

    public synchronized void sub() throws InterruptedException {
   

        while (num == 0) this.wait();
        num --;
        System.out.println(Thread.currentThread().getName() + " " + num);
        this.notifyAll();

//        if (num == 1) {
   
//            num --;
//            System.out.println(Thread.currentThread().getName() + " " + num);
//            this.notifyAll();
//        }else
//            this.wait();
    }
}

public class ThreadWaitNotifyDemo {
   

    public static void main(String[] args) throws Exception{
   


        AirConditioner airConditioner = new AirConditioner();
        new Thread(() -> {
   
            try {
   
//                for (int i = 0; i < 10; i ++) airConditioner.sub();
                while (true) airConditioner.sub();
            } catch (InterruptedException e) {
   
                e.printStackTrace();
            }
        }, "B").start();
        new Thread(() -> {
   
            try {
   
//                for (int i = 0; i < 10; i ++) airConditioner.add();
                while (true) airConditioner.sub();
            } catch (InterruptedException e) {
   
                e.printStackTrace();
            }
        }, "A").start();

        new Thread(() -> {
   
            try {
   
//                for (int i = 0; i < 10; i ++) airConditioner.add();
                while (true) airConditioner.add();
            } catch (InterruptedException e) {
   
                e.printStackTrace();
            }
        }, "c").start();



        new Thread(() -> {
   
            try {
   
//                for (int i = 0; i < 10; i ++) airConditioner.sub();
                while (true) airConditioner.
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值