Java语言(多线程2(线程死锁、线程协调、生产者消费者模式))

Java语言基础

多线程

一、线程死锁
1. 概述

死锁是一种特定的程序状态,在实体之间,由于循环依赖导致彼此一直处于等待之中,没有任何个体可以继续前进,导致两个或者多个线程都在等待对方释放资源 , 都停止执行的情形;死锁不仅仅在线程之间会发生,存在资源独占的进程之间同样也可能出现死锁。通常来说,指两个或多个线程之间,由于互相持有对方需要的锁,互相等待,而永久处于阻塞状态。

2. 演示

这个程序由于线程出现死锁,故一直处于运行状态

public class ThreadDeadLock {

    public static void main(String[] args) {
        DeadLockA deadLockA = new DeadLockA();
        Thread threadA = new Thread(deadLockA, "线程1");
        DeadLockB deadLockB = new DeadLockB();
        Thread threadB = new Thread(deadLockB, "线程2");
        threadA.start();
        threadB.start();
    }
}
class DeadLockA implements Runnable {
    @Override
    public void run() {
        synchronized ("A") {
            System.out.println(Thread.currentThread().getName() + "持有了A锁,等待B锁。。。");
            synchronized ("B") {
                System.out.println(Thread.currentThread().getName() + "持有了A锁和B锁");
            }
        }
    }
}
class DeadLockB implements Runnable {
    @Override
    public void run() {
        synchronized ("B") {
            System.out.println(Thread.currentThread().getName() + "持有了B锁,等待A锁。。。");
            synchronized ("A") {
                System.out.println(Thread.currentThread().getName() + "持有了B锁和A锁");
            }
        }
    }
}
3. 死锁发生的条件

(1)互斥条件:一个资源每次只能被一个进程使用。
(2)请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
(3)不剥夺条件: 进程已获得的资源,在未使用完之前,不能强行剥夺。
(4)循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

4. 解决方法

wait(): 表示线程一直等待 , 直到其他线程通知 , 与sleep不同 , 会释放锁
wait(long timeout): 指定等待的毫秒数
notify(): 唤醒一个处于等待状态的线程
notifyAll(): 唤醒同一个对象上所有调用wait()方法的线程 , 优先级 别高的线程优先调度

二、 线程协调之生产者&消费者模式

多线程环境下,我们经常需要多个线程的并发和协作。这个时候,就需要了解一个重要的多线程并发协作模型“生产者/消费者模式”。
生产者:指的是负责生产数据的模块(这里模块可能是:方法、对象、线程、进程)。
消费者:指的是负责处理数据的模块(这里模块可能是:方法、对象、线程、进程)。
缓冲区:消费者不能直接使用生产者的数据,它们之间有个“缓冲区”。生产者将生产好的数据放入“缓冲区”,消费者从“缓冲区”拿要处理的数据。

    //产品/食物
public class Product {
    public String name;
    public Product(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
//缓冲区/柜台大小
import java.util.List;
public class ProductPool {
    //定义缓冲区大小为8
    public int maxsize=8;
    //产品的列表
    public List <Product> list;
    public ProductPool(int maxsize, List<Product> list) {
        this.maxsize = maxsize;
        this.list = list;
    }
    //生产者生产产品,放入产品到缓冲区
    public synchronized void push(Product product){
        if (this.list.size()>=this.maxsize){
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        // 生产者生产了一个产品
        this.list.add(product);
        // 通知消费者消费。
        this.notifyAll();
    }
     //消费者消费产品,从缓冲区移除产品
    public synchronized Product pop(){
        // 产品数量不能小于0
        // 如果小于0,就等待生产者生产产品。
        if (this.list.size()<=0){
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        // 消费者消费了一个产品
        Product product = this.list.remove(0);
        // 通知生产者生产产品。
        this.notifyAll();
        return  product;
    }
}
//生产者/厨师
public class Producer implements Runnable
    public ProductPool productPool;
    public Producer(ProductPool productPool) {
        this.productPool = productPool;
    }
    @Override
    public void run() {
        int i=1;
        while (true){
            Product product = new Product("产品名称" + i++);
            this.productPool.push(product);
            System.out.println("生产者生产了产品:" + product.getName());
        }
    }
}
//消费者/顾客
public class Consumer implements Runnable {
    public ProductPool productPool;
    public Consumer(ProductPool productPool) {
        this.productPool = productPool;
    }
    //模拟消费者消费产品
    @Override
    public void run() {
        while (true){
            Product product = this.productPool.pop();
            System.out.println("消费者消费了产品:" + product.getName());
        }
    }
}
//生产者消费者模式
public class MyTest {
    public static void main(String[] args) {
        ProductPool productPool = new ProductPool(8, new LinkedList<>());
        Producer producer = new Producer(productPool);
        Thread thread = new Thread(producer);
        thread.start();
        Consumer consumer = new Consumer(productPool);
        Thread thread1 = new Thread(consumer);
        thread1.start();
    }
}
/*
生产者生产了产品:产品名称1
生产者生产了产品:产品名称2
生产者生产了产品:产品名称3
生产者生产了产品:产品名称4
生产者生产了产品:产品名称5
生产者生产了产品:产品名称6
生产者生产了产品:产品名称7
生产者生产了产品:产品名称8
消费者消费了产品:产品名称1
消费者消费了产品:产品名称2
消费者消费了产品:产品名称3
消费者消费了产品:产品名称4
消费者消费了产品:产品名称5
消费者消费了产品:产品名称6
消费者消费了产品:产品名称7
消费者消费了产品:产品名称8
生产者生产了产品:产品名称9
...
*/

//未完待续,后面补充…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值