文章目录

  • 前言
  • 一、JUC简介
    • 1、出自哪位大神之手?
    • 2、JUC是什么?
  • 二、JUC主要解决什么问题?
    • 1、进程 、线程
    • 2、并发、并行
    • 3、JAVA创建线程的方式(模拟三种线程实现方式)
      • 1)继承Thread类(线程的初级用法)
      • 2)实现Runnable 接口(线程的初级用法)
      • 3)内部类方式(线程的中级用法)
      • 4) 使用lamada 表达式实现(高级用法,也是企业中最常使用的方法)
  • 总结

前言

随着JAVA程序员越来越卷,导致现在他们需要不断的学习更深的知识来达到卷的资本。本期系统教程主要介绍JUC,这一章就让我们从头来认识一下它吧,做为一名资深的JAVA程序员,你必需知道什么是JUC,JUC是用来做什么的,怎么用。这也是大厂面试必问技术之一。


一、JUC简介

1、出自哪位大神之手?

  • JUC 是美国的一位大学教师 Doug Lea (道格·利)设计并开发出来的。
  • Doug Lea 服务于纽约州立大学Oswego分校计算机学系的教师。
  • Doug Lea 是 JCP(JAVA社区项目)中的一员。
  • 让我们瞻仰一下大神的容貌,多向大神学习。

2、JUC是什么?

  • JUC是 JDK中java.util.concurrent 包的简称(中文简称:并发工具包),它包含三个包:

    • java.util.concurrent
    • java.util.concurrent.atomic
    • java.util.concurrent.locks
  • 是2004年10月发布的JDK1.5新增用来编写并发相关的基础api。
  • 目前JUC泛指JAVA多线程开发技术。

二、JUC主要解决什么问题?

JUC 主要解决的问题是:在高内聚低耦合的前提下,线程如何操作 资源类可以达到高并发高可用的效果?

先来学习一下几个基本概念

1、进程 、线程

  • 进程:

    • 操作系统可调配的最小单元。
    • 有自己独立的空间。
    • 比如:系统中运行的QQ、CF、王者,它们都是独立的进程。
  • 线程:
    • 线程是进程可中可调配的最小单元。
    • 一个进程内可以包含多个线程。
    • 如:360卫士里包含了许多功能,杀毒、下载软件等,它们是一个进程内不同的线程。

2、并发、并行

  • 并发:

    • 同一个功能被同时调用。
    • 同一段程序被同时调用。
  • 并行:
    • 不同的功能被同时调用。
    • 不同的程序被同时调用。

JUC就是解决多线程执行中遇到的问题,所以我们再来看一下JAVA里是怎么创建线程和操作线程的

3、JAVA创建线程的方式(模拟三种线程实现方式)

模拟一个多线程的需求:火车售票员 A、B、C三个人同时出售一列火车的10张票,售完为止。

1)继承Thread类(线程的初级用法)

使用JUC中的Lock实现不现线程对同一资源的操作
售票员类:

package com.juc.study;import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;/*** 火车售票员*/
public class TrainConductor extends Thread {public TrainConductor() {}public TrainConductor(String name) {super(name);}/*** 售票*/public void saleTickets() {// JUC中的锁,是轻量级的锁,实现类是可重入锁,// 意味着只要有人释放锁,另外一个人就可以重新拿到锁并执行。Lock lock = new ReentrantLock();lock.lock();try {if(Ticket.nums > 0) {System.out.println(Thread.currentThread().getName() + "\t 卖出第:" + (Ticket.nums--) + "张,\t 还剩下:" + Ticket.nums);}} catch (Exception e) {e.printStackTrace();} finally {lock.unlock();}}@Overridepublic void run() {for(int i = 70; i > 0; i--) {saleTickets();}}
}

火车票类:

package com.juc.study;public class Ticket {public static int nums = 10;}

执行类:

import com.juc.study.Ticket;
import com.juc.study.TrainConductor;public class TestJUC {public static void main(String[] args) {// 新建三个售票员TrainConductor trainConductorA = new TrainConductor("A");TrainConductor trainConductorB = new TrainConductor("B");TrainConductor trainConductorC = new TrainConductor("C");// 开始售票trainConductorA.start();trainConductorB.start();trainConductorC.start();}}

执行结果:

A     卖出第:9张,   还剩下:8
C    卖出第:8张,   还剩下:7
B    卖出第:10张,  还剩下:8
C    卖出第:6张,   还剩下:5
C    卖出第:4张,   还剩下:3
A    卖出第:7张,   还剩下:6
C    卖出第:3张,   还剩下:2
C    卖出第:1张,   还剩下:0
A    卖出第:2张,   还剩下:1
B    卖出第:5张,   还剩下:4

2)实现Runnable 接口(线程的初级用法)

与继承Thead类的写法有点区别,大家注意观察
售票员类:

package com.juc.study;import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;/*** 售票员类*/
public class TrainConductorRunnable implements Runnable{/*** 售票*/public void saleTickets() {// JUC中的锁,是轻量级的锁,实现类是可重入锁,// 意味着只要有人释放锁,另外一个人就可以重新拿到锁并执行。Lock lock = new ReentrantLock();lock.lock();try {if(Ticket.nums > 0) {System.out.println(Thread.currentThread().getName() + "\t 卖出第:" + (Ticket.nums--) + "张,\t 还剩下:" + Ticket.nums);}} catch (Exception e) {e.printStackTrace();} finally {lock.unlock();}}@Overridepublic void run() {for(int i = 70; i > 0; i--) {saleTickets();}}
}

火车票类(无变化):

package com.juc.study;public class Ticket {public static int nums = 10;}

执行类:

import com.juc.study.Ticket;
import com.juc.study.TrainConductor;
import com.juc.study.TrainConductorRunnable;public class TestJUC {public static void main(String[] args) {// 新建三个售票员TrainConductorRunnable trainConductorA = new TrainConductorRunnable();TrainConductorRunnable trainConductorB = new TrainConductorRunnable();TrainConductorRunnable trainConductorC = new TrainConductorRunnable();// 新建三个线程Thread t1 = new Thread(trainConductorA, "A");Thread t2 = new Thread(trainConductorB, "B");Thread t3 = new Thread(trainConductorC, "C");// 开始售票t1.start();t2.start();t3.start();}}

执行结果:

A     卖出第:9张,   还剩下:7
C    卖出第:8张,   还剩下:7
A    卖出第:7张,   还剩下:6
B    卖出第:10张,  还剩下:7
A    卖出第:5张,   还剩下:4
C    卖出第:6张,   还剩下:5
A    卖出第:3张,   还剩下:2
B    卖出第:4张,   还剩下:3
A    卖出第:1张,   还剩下:0
C    卖出第:2张,   还剩下:1

3)内部类方式(线程的中级用法)

使用内部类实现是不需要继承Thread类或实现Runnable接口,大家仔细看

火车售票员类:

package com.juc.study;import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;/*** 火车售票员(采用内部类的形式实现)*/
public class TrainConductorInner {/*** 售票*/public void saleTickets() {// JUC中的锁,是轻量级的锁,实现类是可重入锁,// 意味着只要有人释放锁,另外一个人就可以重新拿到锁并执行。Lock lock = new ReentrantLock();lock.lock();try {if(Ticket.nums > 0) {System.out.println(Thread.currentThread().getName() + "\t 卖出第:" + (Ticket.nums--) + "张,\t 还剩下:" + Ticket.nums);}} catch (Exception e) {e.printStackTrace();} finally {lock.unlock();}}}

火车票类(无变化):

package com.juc.study;public class Ticket {public static int nums = 10;}

执行类:

import com.juc.study.Ticket;
import com.juc.study.TrainConductorInner;public class TestJUC {public static void main(String[] args) {Thread t1 = new Thread("A") {@Overridepublic void run() {for(int i = 70; i > 0; i--) {TrainConductorInner a = new TrainConductorInner();a.saleTickets();}}};t1.start();Thread t2 = new Thread("B") {@Overridepublic void run() {for(int i = 70; i > 0; i--) {TrainConductorInner b = new TrainConductorInner();b.saleTickets();}}};t2.start();Thread t3 = new Thread("C") {@Overridepublic void run() {for(int i = 70; i > 0; i--) {TrainConductorInner c = new TrainConductorInner();c.saleTickets();}}};t3.start();}}

4) 使用lamada 表达式实现(高级用法,也是企业中最常使用的方法)

lamada表达式写完之后有点长,如果看不懂可以给它格式化一下

火车售票员类(仍然使用内部类,没变化):

package com.juc.study;import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;/*** 火车售票员(采用内部类的形式实现)*/
public class TrainConductorInner {/*** 售票*/public void saleTickets() {// JUC中的锁,是轻量级的锁,实现类是可重入锁,// 意味着只要有人释放锁,另外一个人就可以重新拿到锁并执行。Lock lock = new ReentrantLock();lock.lock();try {if(Ticket.nums > 0) {System.out.println(Thread.currentThread().getName() + "\t 卖出第:" + (Ticket.nums--) + "张,\t 还剩下:" + Ticket.nums);}} catch (Exception e) {e.printStackTrace();} finally {lock.unlock();}}}

火车票类(没变化):

package com.juc.study;public class Ticket {public static int nums = 10;}

执行类(这里使用lamada表达式):

import com.juc.study.Ticket;
import com.juc.study.TrainConductorInner;public class TestJUC {public static void main(String[] args) {new Thread(()->{for(int i = 70; i > 0; i--){TrainConductorInner a = new TrainConductorInner(); a.saleTickets();}}, "A").start();new Thread(()->{for(int i = 70; i > 0; i--){TrainConductorInner b = new TrainConductorInner(); b.saleTickets();}}, "B").start();new Thread(()->{for(int i = 70; i > 0; i--){TrainConductorInner c = new TrainConductorInner(); c.saleTickets();}}, "C").start();}}

总结

最重要的一句话:在高内聚低耦合的前提下,线程操作资源类达到高并发高可用的效果就是JUC的任务。
JUC的入门就到这里,到这里大家应该会对JUC有点感觉了,感觉是不是挺好玩的,后面的章节更精彩,敬请期待。。。。。。

JUC系列——JUC入门及多线程并发相关推荐

  1. 并发编程JUC系列及部分问题

    什么是 CAS 吗? CAS(Compare And Swap)指比较并交换.CAS算法CAS(V, E, N)包含 3 个参数,V 表示要更新的变量,E 表示预期的值,N 表示新值.在且仅在 V 值 ...

  2. JUC系列(一)什么是JUC?

    多线程一直Java开发中的难点,也是面试中的常客,趁着还有时间,打算巩固一下JUC方面知识,我想机会随处可见,但始终都是留给有准备的人的,希望我们都能加油!!! 沉下去,再浮上来,我想我们会变的不一样 ...

  3. Java多线程系列--“JUC锁”03之 公平锁(一)

    概要 本章对"公平锁"的获取锁机制进行介绍(本文的公平锁指的是互斥锁的公平锁),内容包括: 基本概念 ReentrantLock数据结构 参考代码 获取公平锁(基于JDK1.7.0 ...

  4. 突击并发编程JUC系列-ReentrantReadWriteLock

    突击并发编程JUC系列演示代码地址: https://github.com/mtcarpenter/JavaTutorial 本章节将学习 ReentrantReadWriteLock(读写锁),Re ...

  5. Java多线程系列--“JUC原子类”01之 框架

    2019独角兽企业重金招聘Python工程师标准>>> Java多线程系列--"JUC原子类"01之 框架 根据修改的数据类型,可以将JUC包中的原子操作类可以分 ...

  6. Java多线程系列--“JUC原子类”03之 AtomicLongArray原子类

    概要 AtomicIntegerArray, AtomicLongArray, AtomicReferenceArray这3个数组类型的原子类的原理和用法相似.本章以AtomicLongArray对数 ...

  7. Java多线程系列--“JUC线程池”06之 Callable和Future

    转载自  Java多线程系列--"JUC线程池"06之 Callable和Future Callable 和 Future 简介 Callable 和 Future 是比较有趣的一 ...

  8. Java多线程系列--“JUC锁”05之 非公平锁

    转载自:http://www.cnblogs.com/skywang12345/p/3496651.html点击打开链接 概要 前面两章分析了"公平锁的获取和释放机制",这一章开始 ...

  9. Java多线程系列---“JUC锁”01之 框架

    本章,我们介绍锁的架构:后面的章节将会对它们逐个进行分析介绍.目录如下: 01. Java多线程系列--"JUC锁"01之 框架 02. Java多线程系列--"JUC锁 ...

最新文章

  1. 洛谷P1315 观光公交
  2. OSI七层模型加协议
  3. java泛型学习三:受限制的通配符以及泛型方法
  4. SAP 电商云 Spartacus UI 的 proxy facade 是如何调用实际实现类
  5. SAP CRM WebClient UI Text Type 显示的过滤逻辑
  6. php 怎么解析文本,PHP解析自定义纯文本数据库
  7. Java游戏用户登录注册_Java实现多用户注册登录的幸运抽奖
  8. Less or Equal CodeForces - 977C (sort+细节)
  9. C# 使用iTextSharp中间件打印PDF
  10. usb打印机linux识别不了怎么办,打印机usb连接电脑无法识别怎么办_打印机usb插上无响应怎么办-win7之家...
  11. 我发布在Steam的两款游戏
  12. 在线编辑excel文件实现服务器后台存储,及页面还原
  13. 第一章 几何光学的基本定律
  14. 2020-12-20随笔
  15. 网络表示学习相关资料
  16. 分享:ahk官网内容下载
  17. python android自动化元素定位_appium+python android元素定位
  18. 百度SEO:如何进行网站关键字挖掘!
  19. matlab投资案例,组合投资的风险与收益及其MATLAB的实现..doc
  20. Ubuntu20.04LTS安装RTX-3060显卡驱动

热门文章

  1. ubuntu20.04如何安装i3wm?
  2. ubuntu解决不插显示器采用vnc的时候无法正确显示分辨率的问题
  3. vue 移动端适配方案
  4. CentOS7下安装Mesos教程
  5. 廉价冗余磁盘阵列(RAID)介绍 各级RAID的比较
  6. 机器学习系列-数据分析-平行坐标图
  7. 2023年,目前哪家券商办理的融资融券手续费利率最低呢?
  8. 微信小程序使用表单组件实现用户信息搜集问卷调查案例
  9. Linux登录Oracle(二)
  10. 关于 谷歌浏览器主页被劫持的 解决方法