学习系列之并发编程(一)

简介

1.JUC简介

在Java中,线程部分是一个重点。JUC就是java.util .concurrent工具包的简称。这是一个处理线程的工具包,JDK 1.5开始出现的。
在这里插入图片描述

2.线程与进程

1.进程与线程
进程是指处于运行过程中的程序,并且具有一定的独立功能。进程是系统进行资源分配和调度的一个单位。当程序进入内存运行时,即为线程。简而言之,进程是一个程序,或者是一个程序集合。一个进程包含至少一个或多个线程。
java中默认开启的线程:main线程和gc线程
java开启多线程的方法:Thread,Runnable,Callable
2.并发与并行:
并发:多个线程操作同一个资源
并行:多个线程同时执行,线程池
本质问题:CPU的资源得以充分利用

3.锁

java中有两种常用的锁机制,一种是synchronized,另一种是基于juc实现,synchronized是java底层支持的,而concurrent包则是jdk实现。
1.重量级锁Synchronized
在JDK1.5之前都是使用synchronized关键字保证同步的,它可以把任意一个非NULL的对象当作锁。作用于方法时,锁住的是对象的实例(this);当作用于静态方法时,锁住的是Class实例,又因为Class的相关数据存储在永久带PermGen(jdk1.8则是metaspace),永久带是全局共享的,因此静态方法锁相当于类的一个全局锁,会锁所有调用该方法的线程;synchronized作用于一个对象实例时,锁住的是所有以该对象为锁的代码块。Synchronized是非公平锁。
2.Lock
Lock是一个接口。主要有如下关系:
在这里插入图片描述
3.二者区别
Lock与synchronized有以下区别:
Lock是一个接口,而synchronized是关键字。
synchronized会自动释放锁,而Lock必须手动释放锁。如果不释放会产生死锁问题。
Lock可以让等待锁的线程响应中断,而synchronized不会,线程会一直等待下去。
通过Lock可以知道线程有没有拿到锁,而synchronized不能。
Lock能提高多个线程读操作的效率。
synchronized能锁住类、方法和代码块,而Lock是块范围内的。
synchronized适合少量的代码同步问题,Lock适合锁大量的同步代码。
synchronized是可重入锁,不可以中断,非公平;Lock是可重入锁。

4.生产者消费者

1.Synchronized实现
创建资源类:

class  Data{
    private int num = 0;

    /**
     * @description 生产者 数量+1
    */
    public synchronized void incre() throws InterruptedException {
        while (num!=0){
            this.wait();
        }
        num++;
        System.out.println(Thread.currentThread().getName()+"====>"+num);
        this.notifyAll();
    }

    /**
     * @description 消费者 数量-1
    */
    public synchronized void decr() throws InterruptedException {
        while (num==0){
            this.wait();
        }
        num--;
        System.out.println(Thread.currentThread().getName()+"====>"+num);
        this.notifyAll();
    }
}

注:用while做条件判断:因为if判断会存在虚假唤醒,jdk官方推荐使用while
创建操作main函数

public class ProdConsumSyncTest {

     public static void main(String[] args) {
        Data data = new Data();
        new Thread(
                ()->{
                    for (int i = 0; i <10 ; i++) {
                        try {
                            data.incre();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
        ,"A").start();
        new Thread(
                ()->{
                    for (int i = 0; i <10 ; i++) {
                        try {
                            data.decr();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
                ,"B").start();
        new Thread(
                ()->{
                    for (int i = 0; i <10 ; i++) {
                        try {
                            data.incre();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
                ,"C").start();
        new Thread(
                ()->{
                    for (int i = 0; i <10 ; i++) {
                        try {
                            data.decr();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
                ,"D").start();
    }

}

2.使用Lock实现

public class ProdConsumLockTest {
    public static void main(String[] args) {
        Data1 data = new Data1();
        new Thread(
                ()->{
                    for (int i = 0; i <10 ; i++) {
                        try {
                            data.increment();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
                ,"A").start();

        new Thread(
                ()->{
                    for (int i = 0; i <10 ; i++) {
                        try {
                            data.decrement();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }

        ,"B").start();

        new Thread(
                ()->{
                    for (int i = 0; i <10 ; i++) {
                        try {
                            data.increment();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }

        ,"C").start();

        new Thread(
                ()->{
                    for (int i = 0; i < 10; i++) {
                        try {
                            data.decrement();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }

        ,"D").start();
    }


}

class Data1{
    private int number = 0;
    Lock lock = new ReentrantLock();
    Condition condition = lock.newCondition();
    //condition.await(); // 等待
    // condition.signalAll(); // 唤醒全部
    // +1
    public void increment() throws InterruptedException {
        lock.lock();
        try {
            // 业务代码
            while (number!=0){ //0 // 等待
                 condition.await();
            }
            number++;
            System.out.println(Thread.currentThread().getName()+"=>"+number);
            // 通知其他线程,我+1完毕了
            condition.signalAll();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
    //-1
    public synchronized void decrement() throws InterruptedException {
        lock.lock();
        try {
            while (number==0){
                // 1 // 等待
                condition.await();
            }
            number--;
            System.out.println(Thread.currentThread().getName()+"=>"+number);
            // 通知其他线程,我-1完毕了
            condition.signalAll();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}

参考:狂神说java

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值