010.多线程-线程间通信

版权声明:本文为博主原创文章,允许转载,请标明出处。 https://blog.csdn.net/qwdafedv/article/details/84110475

多线程之间的通信,其实就是多个线程同时操作(读+写)同一个资源。


安全问题:
当线程在读取资源的过程中,写线程操作了资源,
导致读线程读取的数据,一部分是写之前的数据,一部分是写之后的数据。


解决安全问题:
读线程和写线程使用同一把对象锁就好了。


code of demo:

package cn.qbz.thread;

/**
 * 线程间通信
 */
public class ConnectThreadTest {

    public static void main(String[] args) {
        Student student = new Student();
        ProduceTest produceTest = new ProduceTest(student);
        ConsumerTest consumerTest = new ConsumerTest(student);

        produceTest.start();
        consumerTest.start();

    }
}

class ProduceTest extends Thread {
    private Student student;

    public ProduceTest(Student student) {
        this.student = student;
    }

    @Override
    public void run() {
        int num = 1;
        while (true) {
            synchronized (student) {
                //如果可以生产,生产者生产
                if (student.getCanProduce()) {
                    if (num == 1) {
                        student.setAge(6);
                        student.setName("小王");
                        num = 0;
                    } else {
                        student.setName("老王");
                        student.setAge(99);
                        num = 1;
                    }

                    //重置生产者不可以生产
                    student.setCanProduce(false);
                }

                student.notifyAll();
                try {
                    student.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

class ConsumerTest extends Thread {
    private Student student;

    public ConsumerTest(Student student) {
        this.student = student;
    }

    @Override
    public void run() {
        while (true) {
            synchronized (student) {
                //如果不可以生产,进行消费
                if (!student.getCanProduce()) {
                    //重置生产者可以生产
                    student.setCanProduce(true);
                    System.out.println(student.toString());
                }

                student.notifyAll();
                try {
                    student.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

class Student {
    private String name;
    private Integer age;
    private Boolean canProduce = false;

    public Boolean getCanProduce() {
        return canProduce;
    }

    public void setCanProduce(Boolean canProduce) {
        this.canProduce = canProduce;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

wait 和 sleep
共同点: 都是休眠,都释放CPU资源

不同点:
wait必须用于同步中,释放锁,sleep哪里都可以用,且不释放锁。
wait必须使用notify或notifyAll来唤醒,sleep时间到了就会唤醒。

猜你喜欢

转载自blog.csdn.net/qwdafedv/article/details/84110475