进程: 就是一个程序, 里面包含多个线程, 比如一个QQ程序

线程: 进程中最小的调度单元, 比如 QQ中的自动保存功能

并发: 多个线程操作同一资源, 抢夺一个cpu的执行片段, 快速交替

并行: 多个线程一起执行

线程有几个状态: NEW(新) , RUNNABLE(运行) , BLOCKED(阻塞) , WAITING(无限等待) , TIMED_WAITING(超时等待) , TERMINATED(死亡)

他们之前相互转换关系:

1、新建(new):线程对象被创建后就进入了新建状态。如:Thread thread = new Thread();

2、就绪状态(Runnable):也被称为“可执行状态”。线程对象被创建后,其他线程调用了该对象的start()方法,从而启动该线程。如:thread.start(); 处于就绪状态的线程随时可能被CPU调度执行。

3、运行状态(Running):线程获取CPU权限进行执行。需要注意的是,线程只能从就绪状态进入到运行状态。

4、阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权限,暂时停止运行。直到线程进入就绪状态,才有机会进入运行状态。阻塞的三种情况:

----4.1)等待阻塞:通过调用线程的wait()方法,让线程等待某工作的完成。

----4.2)同步阻塞:线程在获取synchronized同步锁失败(因为锁被其他线程占用),它会进入同步阻塞状态。

----4.3)其他阻塞:通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或超时、或者I/O处理完毕时,线程重新转入就绪状态。

5、死亡状态(Dead):线程执行完了或因异常退出了run()方法,该线程结束生命周期。

经典的卖票案例: 直接上代码

在这里 线程就是单独的 资源类, 属性--方法, 多个线程来操作同一资源, 这样写的好处是解耦

代码, synchronized 版本的经典的卖票案例

//这是一个资源类
class Ticket {
private int num = 300; public synchronized void sale(){
if (num > 0) {
System.out.println(Thread.currentThread().getName()+"票的剩余个数为" + num--);
}
} public static void main(String[] args) {
//多个线程操作同一资源, 这样写解耦,
Ticket ticket = new Ticket(); new Thread(()->{
for (int i = 0; i < 40; i++) {
ticket.sale();
}
},"线程-1").start(); new Thread(()->{
for (int i = 0; i < 40; i++) {
ticket.sale();
}
},"线程-2").start(); new Thread(()->{
for (int i = 0; i < 40; i++) {
ticket.sale();
}
},"线程-3").start();
}
}

代码, Lock 版本的经典的卖票案例:

public class LockDemo {
public static void main(String[] args) {
Ticket_L tick = new Ticket_L();
new Thread(()->{for (int i = 0; i < 40; i++) tick.sale();},"thread-1").start();
new Thread(()->{for (int i = 0; i < 40; i++) tick.sale();},"thread-2").start();
new Thread(()->{for (int i = 0; i < 40; i++) tick.sale();},"thread-3").start();
}
} //这是一个资源类, 还是卖票案例
class Ticket_L {
private int num = 300;
private Lock lock = new ReentrantLock(); public void sale(){
//先加一把锁
lock.lock();
try {
if(num > 0){
System.out.println(Thread.currentThread().getName()+"票的剩余个数为" + num--);
}
} catch (Exception e) {
e.printStackTrace();
}finally {
//释放锁
lock.unlock();
}
}
}

synchronized 和 Lock 区别:

1: synchronized 内置的java关键字, Lock是一个java类

2: synchronized 不能判断获取锁的状态, Lock 可以判断是否获取到了锁,有个方法: lock.tryLock(), 来判断是否已经加了锁

3: synchronized 自动释放锁, Lock必须手动释放锁, 不释放的话,容易造成死锁

4: synchronized 是阻塞的, 比如线程1(获取到锁, 阻塞), 线程2(就等待,一直等待), Lock锁,不一定会一直等下去

5、Synchronized 可重入锁,不可以中断的,非公平;Lock ,可重入锁,可以 判断锁,非公平(可以自己设置);

6、Synchronized 适合锁少量的代码同步问题,Lock 适合锁大量的同步代码!

JUC 并发编程--01,线程,进程,经典卖票案例, juc的写法的更多相关文章

  1. C++ 并发编程 01 线程api

    1.使用多线程的好处: 提高性能,分离关注点  2. 多线程所在头文件 <thread> 3. 使用线程方式为std::thread(functioncall),如: #include & ...

  2. JUC 并发编程--08,线程池,三大方法,七大参数,4种拒绝策略,代码演示

    三大方法: //线程池核心线程数为n, 最大线程数为 n ExecutorService fixedThreadPool = Executors.newFixedThreadPool(n); 源码: ...

  3. Scala 深入浅出实战经典 第68讲:Scala并发编程原生线程Actor、Cass Class下的消息传递和偏函数实战解析

    王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-87讲)完整视频.PPT.代码下载: 百度云盘:http://pan.baidu.com/s/1c0noOt ...

  4. 《转载》Python并发编程之线程池/进程池--concurrent.futures模块

    本文转载自Python并发编程之线程池/进程池--concurrent.futures模块 一.关于concurrent.futures模块 Python标准库为我们提供了threading和mult ...

  5. JUC并发编程学习笔记

    JUC并发编程学习笔记 狂神JUC并发编程 总的来说还可以,学到一些新知识,但很多是学过的了,深入的部分不多. 线程与进程 进程:一个程序,程序的集合,比如一个音乐播发器,QQ程序等.一个进程往往包含 ...

  6. 并发编程 01—— ThreadLocal

    Java并发编程实践 目录 并发编程 01—— ThreadLocal 并发编程 02—— ConcurrentHashMap 并发编程 03—— 阻塞队列和生产者-消费者模式 并发编程 04—— 闭 ...

  7. Java并发编程:线程间协作的两种方式:wait、notify、notifyAll和Condition

    Java并发编程:线程间协作的两种方式:wait.notify.notifyAll和Condition 在前面我们将了很多关于同步的问题,然而在现实中,需要线程之间的协作.比如说最经典的生产者-消费者 ...

  8. 并发编程 13—— 线程池的使用 之 配置ThreadPoolExecutor 和 饱和策略

    Java并发编程实践 目录 并发编程 01—— ThreadLocal 并发编程 02—— ConcurrentHashMap 并发编程 03—— 阻塞队列和生产者-消费者模式 并发编程 04—— 闭 ...

  9. Python3 与 C# 并发编程之~进程先导篇

      在线预览:http://github.lesschina.com/python/base/concurrency/1.并发编程-进程先导篇.html Python3 与 C# 并发编程之- 进程篇 ...

随机推荐

  1. JSON对象与字符串的互换——JSON.parse()和JSON.stringify()

    parse用于从一个字符串中解析出json对象,如 var str = '{"name":"huangxiaojian","age":&qu ...

  2. Python数模笔记-Sklearn(1) 介绍

    1.SKlearn 是什么 Sklearn(全称 SciKit-Learn),是基于 Python 语言的机器学习工具包. Sklearn 主要用Python编写,建立在 Numpy.Scipy.Pa ...

  3. base标签的作用

    base标签可以自定义当前页面的相对路径,不受浏览器当前地址栏的影响,以base标签定义的地址为准 (只对相对路径起作用) <head> <meta charset="UT ...

  4. Mac终端使用tree命令查看目录结构

    使用brew管理tree扩展 brew search tree brew install tree tree

  5. 想要测试Dubbo接口?测试的关键点在哪里?

    Dubbo接口如何测试? 这个dubbo如何测试,dubbo接口测试什么玩意儿?   RPC的有一个类型,叫Dubbo接口. 那这个接口如何测试?测试的关键点在哪里? 这个面试问题,我觉得大家可能就有 ...

  6. 轻量级工具Vite到底牛在哪——一文全知道

    转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 原文参考:https://www.sitepoint.com/vitejs-front-end-build- ...

  7. 【Redis破障之路】四:Jedis基本使用

    在前面我们已经学习了Redis命令行客户端redis-cli的使用,接下来我们了解一下Redis基于Java编程语言的客户端. 在Java语言体系下,有三个常用的Redis客户端Jedis.Redis ...

  8. R语言执行脚本的几种命令

    R CMD BATCH 和 Rscript 使用前都要先添加环境变量 把 C:\Program Files\R\R-3.3.0\bin; 加到"系统变量"的Path 值的最开始 可 ...

  9. ARM64平台编译stream、netperf出错解决办法 解决办法:指定编译平台为alpha [root@localhost netperf-2.6.0]# ./configure –build=alpha

    ARM64平台编译stream.netperf出错解决办法 http://ilinuxkernel.com/?p=1738 stream编译出错信息: [root@localhost stream]# ...

  10. Linux_磁盘管理理论概述

    一.磁盘阵列 1.什么是磁盘阵列? 1️⃣:磁盘整列就是将多块独立的磁盘组合到一起,形成容量大的磁盘组. 2️⃣:将相同的数据存放到不多个的磁盘的不同位置 2.RAID0 1️⃣:RAID0是磁盘整列 ...