Java多线程(六)-线程通信

七.线程通信

在生产者与消费者问题中,生产者和消费者共享同一个资源,且二者之间相互依赖,互为条件。

  • 对于生产者,没有生产产品前,要通知消费者等待,生产之后要通知消费者消费。
  • 对于消费者,消费之后要通知生产者生产新产品以供消费
  • synochronized可阻止并发更新同一个共享资源,实现同步。但不能实现线程之间通信。

解决方法:

1.管程法:生产者将生产的数据放入缓冲区,消费者从缓冲取取出数据

点击查看代码
public class guancheng {
    public static void main(String[] args) {
        Container container = new Container();
        new Productor(container).start();
        new Consumer(container).start();
    }
}

//产品
class Product{

    int id;

    public Product(int id) {
        this.id = id;
    }
}

//消费者
class Consumer extends Thread{

    Container container;

    public Consumer(Container container){
        this.container = container;
    }

    @Override
    public void run() {
        // 消费
        for (int i = 0; i < 100; i++) {
            Product product = container.pop();
            System.out.println("消费了第"+product.id+"个产品");
        }
    }
}

//生产者
class Productor extends Thread{

    Container container;

    public Productor(Container container){
        this.container = container;
    }

    @Override
    public void run() {
        // 生产
        for (int i = 0; i < 100; i++) {
            container.push(new Product(i));
            System.out.println("生产了第"+i+"个产品");
        }
    }
}

//缓冲区
class Container{

    Product[] products = new Product[100];
    // 定义容器大小
    int count = 0;

    public synchronized void push(Product product){
        // 生产者生产产品
        if (count == products.length){
            // 容器满了,通知消费者消费,停止生产
        }
        products[count] = product;
        // 没有满,生产者生产产品
        count++;
    }

    public synchronized Product pop(){
        // 消费者消费产品
        if (count == 0){
            // 没有产品,通知生产者生产
        }
        count--;
        // 消费者消费
        Product product = products[count];
        return product;
    }
}

2.信号灯法:设置标志位

点击查看代码
public class xinhaodeng {
    public static void main(String[] args) {
        Show show = new Show();
        new Player(show).start();
        new Audience(show).start();
    }
}

// 生产者
class Player extends Thread{

    Show show;

    public Player(Show show){
        this.show = show;
    }

    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            if (i%2==0){
                show.act("news->"+i);
            }else {
                show.act("movie->"+i);
            }
        }
    }
}

// 消费者
class Audience extends Thread{

    Show show;

    public Audience(Show show){
        this.show = show;
    }

    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            show.watch();
        }
    }
}

// 产品
class Show{

    String show;
    boolean flag = true;
    // 表演者表演,观众等待true
    // 观众观看,表演者等待false

    public synchronized void act(String show){
        if (!flag){
            // 观众观看,表演者等待
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("表演者表演了"+show);
        this.notifyAll();
        // 通知观众观看
        this.show = show;
        this.flag = !this.flag;
    }

    public synchronized void watch(){
        if (flag){
            // 表演者表演,观众等待
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("观众观看了"+show);
        this.notifyAll();
        // 通知表演者表演
        this.flag = !this.flag;
    }
}

 

上一篇:一步一步学习DVWA渗透测试-(File Inclusion文件包含)-第八次课


下一篇:Windows下Dvwa靶场环境配置(网络攻防)