JUC(一)线程、进程、synchronized、LOCK、锁的对象
什么是JUC
JUC是java.util.concurrent的简写。

java2个默认线程:main、GC
线程和进程
进程:一个应用程序就会启动一个进程
线程:一个进程中会有多个至少1个线程。
Java无法直接创建线程,直接操作硬件,都是定错C++做的
并发:多线程操作同一个资源(CPU1核,模拟多条线程)
并行:多个线程同时执行(CPU多核,多个线程可以同时执行)
package com.xiaobai.demo01;
//打印电脑CPU核数
//CPU 密集型,IO密集型
public class Test1 {
public static void main(String[] args) {
System.out.println(Runtime.getRuntime().availableProcessors());
}
}
并发编程的本质:想充分利用CPU的资源
Lock锁
回顾synchronized
package com.xiaobai.demo01;
public class Test1 {
public static void main(String[] args) {
Stick stick = new Stick();
new Thread(()->{
for (int i = 0; i < 200; i++) {
stick.sale();
}
},"a").start();
new Thread(()->{
for (int i = 0; i < 200; i++) {
stick.sale();
}
},"b").start();
new Thread(()->{
for (int i = 0; i < 200; i++) {
stick.sale();
}
},"c").start();
}
}
class Stick {
private int sticknums = 200;
public synchronized void sale() {
if (sticknums>0){
System.out.println(Thread.currentThread().getName()+"售票成功,票为:" + (sticknums--) + ",余票:" + sticknums);
}
}
}
LOCK锁
ReentrantLock()
无参:非公平锁,默认
有参:(true)公平锁
package com.xiaobai.demo01;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Test2 {
public static void main(String[] args) {
Stick2 stick2 = new Stick2();
new Thread(()->{
for (int i = 0; i < 100; i++) {
stick2.sale();
}
},"a").start();
new Thread(()->{
for (int i = 0; i < 200; i++) {
stick2.sale();
}
},"b").start();
new Thread(()->{
for (int i = 0; i < 200; i++) {
stick2.sale();
}
},"c").start();
}
}
class Stick2 {
private int sticknums = 200;
Lock l = new ReentrantLock();
public void sale() {
l.lock();//加锁
try {
if (sticknums>0){
System.out.println(Thread.currentThread().getName()+"售票成功,票为:" + (sticknums--) + ",余票:" + sticknums);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
l.unlock();//解锁
}
}
}
synchronized 和lock的区别
- synchronized 内置的Java关键字,Lock是一个Java类
- synchronized 无法判断获取锁的庄爱,lock可以判断是否获取到了锁
- synchronized 会自动释放锁,lock必须手动释放锁,如果不释放,就是死锁
- synchronized 线程1获得锁,如果阻塞,那么线程2就要一直等待。lock不会一直等待下去
- synchronized 可重入锁,非公平,lock,可重入锁,可以判断锁,是否公平可自己设置
- synchronized 试用少量代码块,lock试用大量
生产者消费者问题,等待唤醒、虚假唤醒
package com.xiaobai.pc;
/*
* 线程之间的通信问题,生产者和消费者问题 等待唤醒 通知唤醒
* 线程交替执行,A B操作同一个变量 num = 0
* A num+1
* B num-1
*
* */
public class A {
public static void main(String[] args){
Date date = new Date();
new Thread(()->{
try {
for (int i = 0; i < 20; i++) {
date.increment();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
},"a").start();
new Thread(()->{
try {
for (int i = 0; i < 20; i++) {
date.decrement();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
},"b").start();
}
}
class Date{//数字 资源类
private int number = 0;
public synchronized void increment() throws InterruptedException {
if(number!=0){
//等待
this.wait();
}
number++;
System.out.println(Thread.currentThread().getName()+"--->增加--->"+number);
//通知其他线程增加完毕
this.notify();
}
public synchronized void decrement() throws InterruptedException {
if(number==0){
//等待
this.wait();
}
number--;
System.out.println(Thread.currentThread().getName()+"--->减少--->"+number);
//通知其他线程减完毕
this.notify();
}
//+1
//-1
}
问题:怎样解决3个线程以上使用(虚假唤醒问题)
解决方法:if改为while
package com.xiaobai.pc;
/*
* 线程之间的通信问题,生产者和消费者问题 等待唤醒 通知唤醒
* 线程交替执行,A B操作同一个变量 num = 0
* A num+1
* B num-1
*
* */
public class A {
public static void main(String[] args){
Date date = new Date();
new Thread(()->{
for (int i = 0; i < 40; i++) {
try {
date.increment();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"a").start();
new Thread(()->{
for (int i = 0; i < 40; i++) {
try {
date.decrement();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"b").start();
new Thread(()->{
for (int i = 0; i < 40; i++) {
try {
date.increment();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"c").start();
new Thread(()->{
for (int i = 0; i < 40; i++) {
try {
date.decrement();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"d").start();
}
}
class Date{//数字 资源类
private int number = 0;
public synchronized void increment() throws InterruptedException {
while(number!=0){
//等待
this.wait();
}
number++;
System.out.println(Thread.currentThread().getName()+"--->增加--->"+number);
//通知其他线程增加完毕
this.notifyAll();
}
public synchronized void decrement() throws InterruptedException {
while(number==0){
//等待
this.wait();
}
number--;
System.out.println(Thread.currentThread().getName()+"--->减少--->"+number);
//通知其他线程减完毕
this.notifyAll();
}
//+1
//-1
}

浙公网安备 33010602011771号