JUC并发编程
线程和进程
并发、并行
用idea获取CPU核数
线程有多少个状态
6个
在idea中可以查询到
wait与sleep的区别
1.来自不同的类
wait—>object
sleep—>Thread,企业当中,休眠
2.关于锁的释放
wait会释放锁,sleep不会释放锁
3.使用范围是不同的
wait必须在同步代码块中
sleep可以在任意地方
4.是否捕获异常
Lock锁
传统Synchronized
例子:卖票
package gx.uwz.cn.demo01;
/**
真正的多线程开发,公司中的开发,降低耦合性
线程就是一个单独的资源类,没有任何附属的操作
1.属性、方法
*/
public class SaleTickeDemo01 {
public static void main(String[] args) {
//并发:多线程操作同一个资源类,把资源类丢进线程
Ticket ticket= new Ticket();
// lambda表达式(参数)->{代码}
new Thread(()->{
for (int i = 1; i <40 ; i++) {
ticket.sale();
}
},“A”).start();new Thread(()->{ for (int i = 1; i < 40; i++) { ticket.sale(); } },"B").start(); new Thread(()->{ for (int i = 1; i < 40; i++) { ticket.sale(); } },"C").start();
}
}
//资源oop
class Ticket{
// 属性,方法
private int number=30;
// 卖票方式
// synchronized 本质:队列,锁
public synchronized void sale(){
if(number>0){
System.out.println(Thread.currentThread().getName()+“卖出了”+(number–)+“票,剩余:”+number);
}
}
}
新版,含有JUC
lock接口
点击
可以看到
新版卖票
package gx.uwz.cn.demo01;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class SaleTickeDemo02 {
public static void main(String[] args) {
Ticket2 ticket2=new Ticket2();
new Thread(()->{
for (int i = 1; i < 40; i++) ticket2.sale();
},“A”).start();
new Thread(()->{
for (int i = 1; i < 40; i++) ticket2.sale();
},“B”).start();
new Thread(()->{
for (int i = 1; i < 40; i++) ticket2.sale();
},“C”).start();
}
}
//lock三部曲
//1. new ReentrantLock();
//2.lock.lock();加锁
//3.finally=>lock,unlock();解锁
class Ticket2{
private int number=30;
Lock lock=new ReentrantLock();
public void sale(){
// 加锁
lock.lock();
try {
// 业务代码
if (number>0){
System.out.println(Thread.currentThread().getName()+“卖出了”+(number–)+“票,剩余:”+number);
}
}catch (Exception e){
e.printStackTrace();
}finally {
// 解锁
lock.unlock();
}
}
}
Synchronized和Lock的区别
lock锁不一定会等。它可以尝试获得锁,以下是获得锁的代码
生产者与消费者问题
Synchronized版(只要是并发一定要有锁)
package gx.uwz.cn.demo01;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
线程之间的通信问题:生产者与消费者问题!等待唤醒,通知唤醒
线程交替执行A B 操作同一个变量 num=0
A: num+1
B:num-1
*/
public class A {
public static void main(String[] args) {
Data data = new Data();
new Thread(()->{
for (int i = 0; i <10 ; i++) {
try {
data.increment();
} catch (InterruptedException e) {
e.printStackTrace();
}} },"A").start(); new Thread(()->{ for (int i = 0; i <10 ; i++) { try { data.decrement(); } catch (InterruptedException e) { e.printStackTrace(); } } },"B").start(); new Thread(()->{ for (int i = 0; i <10 ; i++) { try { data.increment(); } catch (InterruptedException e) { e.printStackTrace(); } } },"C").start(); new Thread(()->{ for (int i = 0; i <10 ; i++) { try { data.decrement(); } catch (InterruptedException e) { e.printStackTrace(); } } },"D").start();
}
}
//判断等待,业务,通知
//数字 ,资源类
class Data{
private int number=0;
// +1
public synchronized void increment() throws InterruptedException {
//原本是if
while (number!=0){
// 等待
this.wait();
}
number++;
System.out.println(Thread.currentThread().getName()+“=>”+number);
// 通知其他线程,我+1完毕
this.notifyAll();
}
// -1
public synchronized void decrement() throws InterruptedException {
//原本是if
while (number==0){
// 等待
this.wait();
}
number–;
System.out.println(Thread.currentThread().getName()+“=>”+number);
// 通知其他线程,我-1完毕
this.notifyAll();
}
}
JUC版
//判断等待,业务,通知
//数字 ,资源类
class Data2{
private int number =0;
Lock lock=new ReentrantLock();
Condition condition=lock.newCondition();
// condition.await();等待
// condition.signalAll();唤醒全部
public void increment() throws InterruptedException {
lock.lock();
try {
while (number!=0){
condition.await();
}
number++;
System.out.println(Thread.currentThread().getName()+"=>"+number);
condition.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void decrement() throws InterruptedException {
lock.lock();
try {
while (number==0){
condition.await();
}
number--;
System.out.println(Thread.currentThread().getName()+"=>"+number);
condition.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
public class B {
public static void main(String[] args) {
Data2 data2 = new Data2();
new Thread(()->{
for (int i = 0; i <10 ; i++) {
try {
data2.increment();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},“A”).start();
new Thread(()->{
for (int i = 0; i <10 ; i++) {
try {
data2.decrement();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},“B”).start();
new Thread(()->{
for (int i = 0; i <10 ; i++) {
try {
data2.increment();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},“C”).start();
new Thread(()->{
for (int i = 0; i <10 ; i++) {
try {
data2.decrement();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},“D”).start();
}
}
解决上述问题
package gx.uwz.cn.demo01;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
- A执行完调用B,B执行完调用C,C执行完调用A
*/
public class C {
public static void main(String[] args) {
Data3 data3 = new Data3();
new Thread(()->{
for (int i = 0; i <10 ; i++) {
data3.printA();
}
},“A”).start();
new Thread(()->{
for (int i = 0; i <10 ; i++) {
data3.printB();
}
},“B”).start();
new Thread(()->{
for (int i = 0; i <10 ; i++) {
data3.printC();
}
},“C”).start();
}
}
class Data3{
private Lock lock=new ReentrantLock();
private Condition condition1=lock.newCondition();
private Condition condition2=lock.newCondition();
private Condition condition3=lock.newCondition();
private int number=1;
public void printA(){
lock.lock();
try {
// 业务,判断-》执行-》通知
while (number!=1){
condition1.await();
}
System.out.println(Thread.currentThread().getName()+“=>AAAAAAA”);
// 唤醒,指定为B
number=2;
condition2.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void printB(){
lock.lock();
try {
while (number!=2){
condition2.await();
}
System.out.println(Thread.currentThread().getName()+"=>BBBBBB");
// 唤醒,指定为C
number=3;
condition3.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void printC(){
lock.lock();
try {
while (number!=3){
condition3.await();
}
System.out.println(Thread.currentThread().getName()+"=>CCCCCC");
// 唤醒,指定为A
number=1;
condition1.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}