芯が強い人になるESTJ-A

# JUC多线程+并发编程

IT開発 Tags: 无标签 阅读: 296

多线程方法一:synchronized==本质是排队

package com.xuwen.demo01;

/**
 * author:xuwen
 * Created on 2021/8/31
 */
public class SaleTicketDemo {
    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(本质排队)
    //并发解决方法synchronized
    public synchronized void sale(){
        if(number>0){
            System.out.println(Thread.currentThread().getName()+"卖出了"+(number--)+"票,剩余数量:"+number);
        }
    }
}

多线程方法二:lock三部曲,new ReentrantLock,加锁,trycatch,解锁

package com.xuwen.demo01;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * author:xuwen
 * Created on 2021/8/31
 */
public class SaleTicketDemo02 {
    public static void main(String[] args) {
        //并发,多个线程操作一个资源类,把资源类丢入线程
        Ticket2 ticket = new Ticket2();
        //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,属性+方法,结偶
//lock三部曲,new ReentrantLock,加锁,trycatch,解锁
class Ticket2{
    //属性,方法
    private int number = 30;

    Lock lock = new ReentrantLock();

    //方法二:lock锁
    public void sale(){
        //加锁,trycatch,解锁
        lock.lock();
        try {
            if(number>0){
                System.out.println(Thread.currentThread().getName()+"卖出了"+(number--)+"票,剩余数量:"+number);
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }

    }
}

synchronized和lock区别
1Synchronized是一个java关键字,Lock是java的类

2Synchronized自动,无法判断锁的状态,Lock可以判断
3Sync是自动释放锁,Lock必需手动解锁,释放锁。如果没释放-》死锁
4sync线程1(获得锁,阻塞),线程2(等待,傻傻的等待);Lock,手动挡,lock.trylock()
5sync可重入锁,不可中断,非公平,Lock可重入锁,可以判断锁,非公平(自己设置)

生产者消费者问题

sync版,旧版

虚假唤醒问题,把if修改成while

截屏2021-08-31 14.39.15.jpg
截屏2021-08-31 14.52.59.jpg

需要把if换成while

package com.xuwen.proconsume;

/**
 * author:xuwen
 * Created on 2021/8/31
 */

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();

    }


}


//八字口诀!!资源,等待,业务,通知
class Data{
    //资源
    private int number =0;


    //+1
    public synchronized void increment() throws InterruptedException {
        while(number !=0){
            //等待
            this.wait();
        }
        number++;
        System.out.println(Thread.currentThread().getName()+"->"+number);
        //通知
        this.notifyAll();

    }


    //-1
    public synchronized void decrement() throws InterruptedException {
        while(number ==0){
            //等待
            this.wait();
        }
        number--;
        System.out.println(Thread.currentThread().getName() + "->" + number);
        //通知
        this.notifyAll();
    }

}
JUC版,新版,生产者消费者问题

截屏2021-08-31 14.55.51.jpg
截屏2021-08-31 14.57.01.jpg