JUC并发编程
JUC并发编程
Java.util工具包
Java.util.concurrent
业务:普通的线程代码Thread
Runnable没有返回值,效率比Callable相对较低
以前学的里面:Callable、ReentrantLock等都是java.util.concurrent包里面的
线程和进程
进程:一个程序
一个进程可以包含多个线程,至少包含一个线程
java默认有两个线程,main和GC
线程:
Java真的可以开启线程吗?不可以
只能通过本地方法去调用底层C++,Java无法直接操作硬件
private native void start0();
并发和并行
并发才存在多线程的说法,多线程操作同一个资源
- CPU一核,模拟出来多条线程,快速交替产生的假象
并行:多个人一起行走
- CPU多核,多个线程可以同时执行;线程池
- 获取CPU核数
Runtime.getRunTime().avaliableProcessors()
并发编程的本质:充分利用CPU的资源
线程的六个状态
NEW, RUNNABLE, BLOCKED, WAITING死等, TIMED_WAITING超时等待, TERMINATED
wait/sleep区别
-
来自不同的类 wait-object类、sleep-Thread类
企业中一般用
TimeUnit.DAYS.sleep(1);属于JUC包 -
锁的释放:wait会释放锁,sleep抱着锁睡,不释放
-
使用范围不同:wait只能在同步代码块中使用,sleep可以在任何地方
-
捕获异常:wait不需要,sleep需要捕获异常
lock锁(重点)
传统 synchronized
/*
真正的多线程开发,公司中的开发,降低耦合性
线程就是一个单独的资源类,没有任何附属的操作
1.属性、方法
*/
public class SaleTicketDemo1{
public static void main(String[] args){
//并发:多线程操作同一个资源类,把资源类丢入线程
Ticket ticket = new Ticket();
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 = 40;
//synchronized本质:队列,锁
public synchronized void sale(){
if(number > 0){
System.out.println(Thread.currentThread().getName()+"卖出了"+(number--)+"票");
}
}
}
Lock接口
三个实现类:ReentrantLock(常用),ReadLock,WriteLock
public class SaleTicketDemo2{
public static void main(String[] args){
//并发:多线程操作同一个资源类,把资源类丢入线程
Ticket2 ticket = new Ticket2();
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 Ticket2{
//属性、方法
private int number = 40;
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();//解锁
}
}
}
公平锁&非公平锁
公平锁:必须先来后到
非公平锁(默认) :可以插队,根据CPU分配
Lock和synchronized的区别
-
synchronized是内置的Java关键字,lock是Java类
-
synchronized无法判断获取锁的状态,lock可以判断是否获取到了锁
-
synchronized会自动释放锁,lock锁必须手动释放锁,不释放会造成死锁
-
synchronized线程1(获得锁但是阻塞)线程2(一直等待),lock锁不一定会一直等待
lock.trylock();尝试获取锁 -
synchronized可重入锁,不可以中断的,非公平锁,lock可重入锁,可以判断锁,非公平锁(可以自己设置)
-
synchronized适合锁少量的代码同步问题,lock适合锁大量的同步代码
锁是什么?如何判断锁的是谁

浙公网安备 33010602011771号