JUC编程01:初识JUC

一、什么是JUC

1、概念

  • JUC就是 java.util 下的工具包、包、分类等。
    在这里插入图片描述

二、线程知识回顾

1、进程与线程

  • 进程:
    ①、一个程序,QQ.exe Music.exe 程序的集合;
    ②、一个进程往往可以包含多个线程,至少包含一个!
    ③、Java默认有2个线程? mian、GC

  • 线程
    ①、例如编写文档时,编写的操作和自动保存属于两个不同的线程
    ②、对于Java而言提供了:Thread、Runnable、Callable操作线程。

2、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();

java时不能直接开启线程的,最后是通过调用本地方法,底层为c++操作

3、并发与并行

并发

  • 多线程操作同一个资源。
  • 一核CPU,模拟出来多条线程,快速交替。

并行:

  • 多核CPU ,多个线程可以同时执行
public class Test1 {
    public static void main(String[] args) {
      // 获取cpu的核数 
        System.out.println(Runtime.getRuntime().availableProcessors());
     // 如果电脑是8核,则结果输出8
     } 
}

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

4、线程的6个状态

public enum State {

    NEW:线程新生状态
 
    RUNNABLE:线程运行中

    BLOCKED:线程阻塞状态

    WAITING:线程等待状态,死等
 
    TIMED_WAITING:线程超时等待状态,超过一定时间就不再等

    TERMINATED:线程终止状态,代表线程执行完毕
}

5、wait和sleep的区别

①、来自不同的类

  • wait => Object
  • sleep => Thread

②、关于锁的释放

  • wait 会释放锁
  • sleep 睡觉了,抱着锁睡觉,不会释放

③、使用的范围是不同的

  • wait 必须在同步代码块中使用
  • sleep 可以在任何地方睡眠

三、Synchronized锁和Lock锁

1、Synchronized锁买票例子


public class SaleTicketTDemo01 {
    /*
     * 真正的多线程开发,公司中的开发,降低耦合性
     * 线程就是一个单独的资源类,没有任何附属的操作!
     * 1、 属性、方法
     */
    public static void main(String[] args) {
        //并发:多个线程同时操作一个资源类,把资源类丢入线程
        Ticket ticket = new Ticket();
        // @FunctionalInterface 函数式接口,jdk1.8 lambada表达式
        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();
    }
}
//资源类 OOP
class Ticket {
    //属性、方法
    private int number = 50;
    // 卖票的方式
    // synchronized 本质: 队列,锁
    public synchronized void sale() {
        if (number > 0) {
            System.out.println(Thread.currentThread().getName() + "卖出了" +
                    (50-(--number)) + "张票,剩余:" + number + "张票");
        }
    }
}

2、Lock锁

在这里插入图片描述
在这里插入图片描述

  • 公平锁:十分公平,线程执行顺序按照先来后到顺序
  • 非公平锁:十分不公平:可以插队 (默认锁)
  • Lock锁买票例子

public class SaleTicketTDemo02 {
    public static void main(String[] args) {
        //并发:多个线程同时操作一个资源类,把资源类丢入线程
        Ticket2 ticket = new Ticket2();
        // @FunctionalInterface 函数式接口,jdk1.8 lambada表达式
        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();
    }
}
//Lock 3步骤
// 1. new ReentrantLock();
// 2. lock.lock()  加锁
// 3. lock.unlock() 解锁
class Ticket2 {
    //属性、方法
    private int number = 50;
    Lock lock = new ReentrantLock();
    // 卖票方式
    public void sale() {
        lock.lock();// 加锁
        try {
            // 业务代码
            if (number > 0) {
                System.out.println(Thread.currentThread().getName() + "卖出了" +
                        (50 - (--number)) + "张票,剩余:" + number + "张票");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();// 解锁
        }
    }
}

Synchronized 和 Lock 区别:

  • Synchronized 是内置的Java关键字; Lock 是一个Java类
  • Synchronized 无法判断获取锁的状态;Lock 可以判断是否获取到了锁
  • Synchronized 会自动释放锁;lock 必须要手动释放锁!如果不释放锁,就会死锁
  • Synchronized 线程 1(获得锁,如果线程1阻塞)、线程2(等待,傻傻的等);Lock锁就不一定会等待下去
  • Synchronized 可重入锁,不可以中断的,非公平;Lock ,可重入锁,可以判断锁,非公平(可以自己设置)
  • Synchronized 适合锁少量的代码同步问题;Lock 适合锁大量的同步代码
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

微笑AJJD

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值