JUC(1)基本知识及Lock锁

什么是JUC

JUC是java.util.concurrent的简写。在jdk官方手册中可以看到juc相关的jar包有三个。
用中文概括一下,JUC的意思就是java并发编程工具包!
在这里插入图片描述

回顾线程和进程

  • 进程:一个运行中的程序!是操作系统进行资源分配和调度的基本单位!一个进程可以包含多个线程;java默认有两个线程:main线程;GC线程!
  • 线程:线程是操作系统中进行运算调度的最小单位

java可以开启线程吗?
不可以;因为线程的开启是调用的本地方法start0(),其底层使用的是C++;java无法直接操作硬件!

并发和并行:

并发:多个线程操作同一个资源!

  • 一皇两后就是并发;例如CPU一核的时候,线程之间快速交替,模拟多条线程!

并行:多个人一起行走;可以使用线程池!

  • 两皇一后就是并行 ;例如CPU多核,多个线程可以同时执行!

用代码查看电脑的线程数:

public class Test1 {
    public static void main(String[] args) {
        //获取CPU的核数
        //CPU密集型,IO密集型
        System.out.println(Runtime.getRuntime().availableProcessors());
    }
}

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

线程的几个状态

通过底层可以知道有6个:
NEW(新生),RUNNABLE(运行), BLOCKED(阻塞), WAITING(等待),TIMED_WAITING(超时等待), TERMINATED(终止);

wait和sleep的区别
  1. 来自不同的类;wait来自Object的类;sleep来自Thread类;
  2. 关于锁的释放:wait会释放锁,sleep不会释放锁!
  3. 使用的范围不同:wait必须在同步代码块中;sleep可以在任何地方!
  4. 是否需要捕获异常:只要是线程都会存在中断异常!

LOCK锁(重点!)

传统Synchronized

//仍然使用基本的卖票例子

/**
 * 线程就是一个单独的资源类,没有任何的附属操作
 * 1.属性、方法
 */
 public class SaleTick {
    public static void main(String[] args) {
    //并发:多线程操作同一个类;把资源类丢入线程
        Ticket ticket = new Ticket();
        // 使用lambda表达式 (参数)->{代码} 最好不要写一行,代码可读性变差了!
        new Thread(()->{ for(int i = 1;i<50;i++){ ticket.sale(); } },"A").start();
        new Thread(()->{ for(int i = 1;i<50;i++){ ticket.sale(); } },"B").start();
        new Thread(()->{ for(int i = 1;i<50;i++){ ticket.sale(); } },"C").start();
    }
}

//这里不去实现Runnable接口,可以实现降低耦合!
class Ticket{
    //属性、方法
    private int number = 50;
    //卖票的方式
    public synchronized void sale(){
        if(number >0){
            System.out.println(Thread.currentThread().getName() + "卖出了" + number-- +"票,剩余:" + number +"张票");
        }
    }
}

可以比较这里的卖票代码

Lock接口

通过API文档:使用Lock是在用之前加锁,在用完之后解锁。
在这里插入图片描述
Lock接口有三个实现类:分别如下:
在这里插入图片描述
常用的可重用锁的底层!
在这里插入图片描述
公平锁:十分公平,先来后到,需要排队!
非公平锁:可以插队!(默认)

使用Lock的代码相比于上面只是业务部分改变了:

//使用Lock锁三部曲

/**
 * 1.new 一个锁 new ReentrantLock();
 * 2.加锁
 * 3.解锁
 */
class Ticket{
    //属性、方法
    private int number = 50;
   Lock l = new ReentrantLock();
    public void sale(){
        l.lock();
        try {
            //业务代码  Ctrl+Alt+T 快捷键包含业务代码
            if(number >0){
                System.out.println(Thread.currentThread().getName() + "卖出了" + number-- +"票,剩余:" + number +"张票");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            l.unlock();
        }
    }
}

Synchronized和Lock的区别

通过上面的代码我们可以发现他们之间的区别如下:

  1. Synchronized是一个内置的java关键字;Lock是一个java类;
  2. Synchronized无法判断获取锁的状态,Lock可以判断是否获取到了锁;
  3. Synchronized会自动释放锁,Lock锁必须手动释放锁,如果不释放锁,就会造成死锁!
  4. Synchronized中假如有两个线程:当线程1获得锁的时候,线程2等待;当线程1阻塞时,线程2会一直傻傻的等;Lock锁就不一定会等待下去,因为有一个tryLock()方法会尝试去获得锁!
  5. Synchronized可重入锁,不可中断的,非公平;Lock可重入锁,可以判断锁,可以自己设置公平与非公平!
  6. Synchronized适合锁少量的代码同步问题,Lock适合锁大量的同步代码!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值