并发
并发编程∶并发、并行
并发(多线程操作同一个资源)
CPU一核,模拟出来多条线程,天下武功,唯快不破,快速交替并行(多个人一起行走)
CPU 多核,多个线程可以同时执行;
public class QuickSort { public static void main(String[] args) { //获取cpu核数 System.out.println(Runtime.getRuntime().availableProcessors()); }
线程有六种状态
线程wait 和 sleep的区别
- wait:会释放锁 sleep会抱着锁睡不释放
- wait: sleep:在任何地方睡
- wait:不会捕获异常 sleep:必须要捕获异常
代码来展示并发(传统Synchronized)
public class QuickSort {
public static void main(String[] args) {
//并发,多个线程操作一个资源类 把资源丢入线程
Ticket tic=new Ticket();
//Lambda表达式(参数)->{代码}
/* new Thread(new Runnable() {
@Override
public void run() {
}
}).start();*/
new Thread(()->{
for (int i = 0; i < 60; i++) {
tic.sale();
}
},"A").start();
new Thread(()->{for (int i = 0; i < 60; i++) {
tic.sale();
}},"B").start();
new Thread(()->{for (int i = 0; i < 60; i++) {
tic.sale();
}},"C").start();
}
}
class Ticket{
private int number =50;
public synchronized void sale(){
if(number>0){
System.out.println(Thread.currentThread().getName()+"卖出了"+number--+"剩下"+number);
}
}
}
Lock
公平锁:十分公平 可以分先来后到
非公平锁: 十分不公平 可以插队
public class QuickSort { public static void main(String[] args) { //并发,多个线程操作一个资源类 把资源丢入线程 Ticket tic=new Ticket(); new Thread(new Runnable() { @Override public void run() { } }).start(); new Thread(()->{ for (int i = 0; i < 60; i++) { tic.sale(); } },"A").start(); new Thread(()->{for (int i = 0; i < 60; i++) { tic.sale(); }},"B").start(); new Thread(()->{for (int i = 0; i < 60; i++) { tic.sale(); }},"C").start(); } } /*Lock三部曲 1 new ReentrantLock(); 2 新ReentrantLock() 3 finaLly=> lock. unLock(); (/解锁*/ class Ticket{ private int number=50; Lock lock=new ReentrantLock(); public void sale(){ lock.lock(); if(number>0){ System.out.println(Thread.currentThread().getName()+"卖出了"+number--+"剩下"+number); } lock.unlock(); } }
结果
Synchronized和Lock区别
- Synchronized内置的Java关键字,Lock是一个Java类
- Synchronized 无法判断获取锁的状态,Lock 可以判断是否获取到了锁
- Synchronized 会自动释放锁,lock必须要手动释放锁!如果不释放锁,死锁
- Synchronized线程1(获得锁,阻塞)、线程2(等待,傻傻的等)
- Synchronized可重入锁,不可以中断的,非公平;Lock,可重入锁,可以判断锁,非公平(可以自己设置); 同步可重入锁,不可以中断的,非公平;锁,可重入锁,可以判断锁,非公平(可以自己设置);
什么是锁
生产者和消费者问题
代码
public class QuickSort {
public static void main(String[] args) {
Data data=new Data();
new Thread(()->{
try {
data.printA();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
},"A").start();
new Thread(()->{
try {
data.printB();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
},"B").start();
new Thread(()->{
try {
data.printC();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
},"C").start();
}
}
class Data{
private Lock lock=new ReentrantLock();
//监视器condition
private Condition condition =lock.newCondition();
private Condition condition1 =lock.newCondition();
private Condition condition2 =lock.newCondition();
private int number=1;
public void printA() throws InterruptedException {
lock.lock();
//业务 判断-》执行-》通知
while (number!=1){
//等待
condition.await();
}
System.out.println(Thread.currentThread().getName()+"A");
number=2;
condition.signal();
lock.unlock();
}
public void printB() throws InterruptedException {
lock.lock();
//业务 判断-》执行-》通知
while (number!=2){
//等待
condition1.await();
}
System.out.println(Thread.currentThread().getName()+"B");
number=3;
condition.signal();
lock.unlock();
}
public void printC() throws InterruptedException {
lock.lock();
//业务 判断-》执行-》通知
while (number!=3){
//等待
condition2.await();
}
System.out.println(Thread.currentThread().getName()+"C");
number=1;
condition.signal();
lock.unlock();
}
}