跟南桑学JUC

1什么式JUC
Java.uitl工具包
包,分类
业务:普通的线程代码Thread
Runnable 没有返回值,效率相比于Callable相对较低
Java.util.concurrent包下的
Lock锁在Java.util.concurren.locks下
2线程和进程
进程:一个程序,QQ.exe,mysic.exe程序的集合;
一个进程往往包含多个线程;至少包含一个
Java默认有几个线程?2个 main和GC线程
线程:开了一个进程:Typora,写字,自动保存(线程负责的)
对于java而言Thread,Runnble,Callable
Java真的可以开启线程吗?
开不了的
Thread部分源码


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

image-20210410110321252

并发、并行

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

  • CPU单核,模拟出来多条线程,天下武功,唯快不破,快速交替

并行(多个人一次行走)

  • CPU多核,多个线程可以同时执行;线程池

查询cpu核数

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

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

03.回顾多线程

线程有几个状态 – 6种

public enum State {
    /**
     * 新建
     */
    NEW,

    /**
     * 运行
     */
    RUNNABLE,

    /**
     * 阻塞
     */
    BLOCKED,

    /**
     * 等待,死死的等
     */
    WAITING,

    /**
     * 超时等待
     */
    TIMED_WAITING,

    /**
     * 停止
     */
    TERMINATED;
}

wait/sleep区别

  1. 来自不同的类

wait -> Object

sleep -> Thread

  1. 关于锁的释放

wait会释放锁

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

  1. 使用的范围是不同的

wait必须在同步代码块中

sleep可以在任何地方睡

  1. 是否需要捕获异常

wait不需要捕获异常

sleep必须捕获异常

04.传统的Synchronized锁

public class SaleTickerDemo01 {
    public static void main(String[] args) {
        Ticket ticket = new Ticket();
        new Thread(() -> {
            for (int i = 0; i < 50; i++) {
                ticket.sale();
            }
        }, "A").start();
        new Thread(() -> {
            for (int i = 0; i < 50; i++) {
                ticket.sale();
            }
        }, "B").start();
        new Thread(() -> {
            for (int i = 0; i < 50; i++) {
                ticket.sale();
            }
        }, "C").start();

    }
}

class Ticket {
    private int number = 50;

    public synchronized void sale() {
        if (number > 0) {
            System.out.println(Thread.currentThread().getName() + "买了第" + (number--) + "张票");
        }
    }
}

输出

A买了第50张票
A买了第49张票
A买了第48张票
A买了第47张票
A买了第46张票
A买了第45张票
B买了第44张票
B买了第43张票
B买了第42张票
B买了第41张票
B买了第40张票
B买了第39张票
B买了第38张票
B买了第37张票
B买了第36张票
B买了第35张票
B买了第34张票
B买了第33张票
B买了第32张票
B买了第31张票
B买了第30张票
B买了第29张票
B买了第28张票
B买了第27张票
B买了第26张票
B买了第25张票
B买了第24张票
B买了第23张票
A买了第22张票
A买了第21张票
A买了第20张票
A买了第19张票
A买了第18张票
A买了第17张票
A买了第16张票
A买了第15张票
A买了第14张票
A买了第13张票
A买了第12张票
A买了第11张票
A买了第10张票
A买了第9张票
A买了第8张票
A买了第7张票
A买了第6张票
A买了第5张票
A买了第4张票
A买了第3张票
A买了第2张票
A买了第1张票

05.Lock锁

加锁,释放锁

image-20210411084754717

实现类(可重入锁,读锁,写锁)

image-20210411085407520

可重入锁构造方法

image-20210411092209197

公平锁:十分公平,可以先来后到

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

public class SaleTickerDemo02 {
    public static void main(String[] args) {
        Ticket2 ticket = new Ticket2();
        new Thread(() -> {
            for (int i = 0; i < 50; i++) {
                ticket.sale();
            }
        }, "A").start();
        new Thread(() -> {
            for (int i = 0; i < 50; i++) {
                ticket.sale();
            }
        }, "B").start();
        new Thread(() -> {
            for (int i = 0; i < 50; i++) {
                ticket.sale();
            }
        }, "C").start();

    }
}

/**
 * 1.创建锁 Lock lock = 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() + "买了第" + (number--) + "张票");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //释放锁
            lock.unlock();
        }
    }
}

06.Synchronized和Lock区别

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值