Java learning summary: 29

Classic operation case between threads-producer and consumer case

Basic program model:

package Project.Study.Multithreading;

class Message{
    private String title;   //保存信息的标题
    private String content; //保存信息的内容
    public void setTitle(String title) {
        this.title = title;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public String getTitle() {
        return title;
    }

    public String getContent() {
        return content;
    }
}
class Producer implements Runnable{		//定义生产者
    private Message msg=null;
    public Producer(Message msg){
        this.msg=msg;
    }
    @Override
    public void run(){
        for (int x=0;x<50;x++){				//生产50次数据
            if(x%2==0){
                this.msg.setTitle("小关");	//定义title属性
                try {
                    Thread.sleep(100);		//延迟操作
                }catch (InterruptedException e){
                    e.printStackTrace();
                }
                this.msg.setContent("学习Java");//设置content属性
            }else{
                this.msg.setTitle("小梁");		//设置title属性
                try {
                    Thread.sleep(100);			//延迟操作
                }catch (InterruptedException e){
                    e.printStackTrace();
                }
                this.msg.setContent("学习python");//设置content属性
            }
        }
    }
}
class Consumer implements Runnable{
    private Message msg;
    public Consumer(Message msg){
        this.msg=msg;
    }
    @Override
    public void run(){
        for(int x=0;x<50;x++){
            try{
                Thread.sleep(100);
            }catch (InterruptedException e){
                e.printStackTrace();
            }
            System.out.println(this.msg.getTitle()+"-->"+this.msg.getContent());
        }
    }
}
public class Test10 {
    public static void main(String []args){
        Message msg=new Message();
        new Thread(new Producer(msg)).start();
        new Thread(new Consumer(msg)).start();
    }
}
//结果:
//小梁-->学习Java
//小关-->学习python
//小梁-->学习Java
//小关-->学习python
//小梁-->学习Java
//小关-->学习python
//小梁-->学习Java
//小关-->学习python
//小梁-->学习Java
//(...)

Originally the expected output of the program is: Xiaoguan-> learning Java, Xiaoliang-> learning python
but obviously there is a problem, the set data is misaligned, the data is repeatedly taken out and set repeatedly.

Solve the problem of data disorder

The data misalignment is entirely due to asynchronous operations, so synchronous processing should be used.
Example: Join the synchronization to solve the problem of data disorder

package Project.Study.Multithreading;

class Message2{
    private String title;   //保存信息的标题
    private String content; //保存信息的内容
    public synchronized void set(String title,String content){
        this.title=title;
        try{
            Thread.sleep(100);
        }catch(InterruptedException e){
            e.printStackTrace();
        }
        this.content=content;
    }
    public synchronized void get(){
        try{
            Thread.sleep(100);
        }catch (InterruptedException e){
            e.printStackTrace();
        }
        System.out.println(this.title+"-->"+this.content);
    }
}
class Producer2 implements Runnable{
    private Message2 meg=null;
    public Producer2(Message2 msg){
        this.meg=msg;
    }
    @Override
    public void run(){
        for(int x=0;x<20;x++){
            if(x%2==0){
                this.meg.set("小关","学习Java");
            }else{
                this.meg.set("小梁","学习Python");
            }
        }
    }
}
class Consumer2 implements Runnable{
    private Message2 msg=null;
    public Consumer2(Message2 msg){
        this.msg=msg;
    }
    @Override
    public void run(){
        for (int x=0;x<20;x++){
            this.msg.get();
        }
    }
}
public class Test11 {
    public static void main(String []args)throws Exception{
        Message2 msg=new Message2();
        new Thread(new Producer2(msg)).start();
        new Thread(new Consumer2(msg)).start();
    }
}
//结果:
//小梁-->学习Python
//小梁-->学习Python
//小梁-->学习Python
//小梁-->学习Python
//(...)

The above procedure solves the problem of data misalignment, but there are still problems of repeated removal and repeated setting.

Resolve data duplication

Object class support for multithreading

No. method Types of description
1 public final void wait() throws InterruptedException ordinary Thread waiting
2 public final void notify() ordinary Wake up the first waiting thread
3 public final void notifyAll() ordinary Wake up all waiting threads

In general, all waiting threads will be arranged in order.
If the notify () method is used, the first waiting thread will be woken up;
if the notifyAll () method is used, all the waiting threads will be woken up . Which thread has the highest priority will be executed first.

Example:

package Project.Study.Multithreading;

class Message3{
    private String title;
    private String content;
    private boolean flag=true;
    //flag==true:表示可以生产,但是不能拿走
    //flag==false:表示可以取走,但是不能生产
    public synchronized void set(String title,String content){
        if(this.flag==false){
            try {
                super.wait();                   //等待
            }catch (InterruptedException e){
                e.printStackTrace();
            }
        }
        this.title=title;
        try {
            Thread.sleep(100);
        }catch (InterruptedException e){
            e.printStackTrace();
        }
        this.content=content;
        this.flag=false;                        //已经生产完成,修改标志位
        super.notify();                         //唤醒等待线程
    }
    public synchronized void get(){
        if (this.flag==true){                   //未生产,不能取走
            try {               
                super.wait();                   //等待
            }catch (InterruptedException e){
                e.printStackTrace();
            }
        }
        try {
            Thread.sleep(100);
        }catch (InterruptedException e){
            e.printStackTrace();
        }
        System.out.println(this.title+"-->"+this.content);
        this.flag=true;                         //已经取走了,可以继续生产
        super.notify();                         //唤醒等待线程
    }
}
class Producer3 implements Runnable{
    private Message3 meg;
    public Producer3(Message3 msg){
        this.meg=msg;
    }
    @Override
    public void run(){
        for(int x=0;x<10;x++){
            if(x%2==0){
                this.meg.set("小关","学习Java");
            }else{
                this.meg.set("小梁","学习Python");
            }
        }
    }
}
class Consumer3 implements Runnable{
    private Message3 msg;
    public Consumer3(Message3 msg){
        this.msg=msg;
    }
    @Override
    public void run(){
        for (int x=0;x<10;x++){
            this.msg.get();
        }
    }
}

public class Test12 {
    public static void main(String []args){
        Message3 msg=new Message3();
        new Thread(new Producer3(msg)).start();
        new Thread(new Consumer3(msg)).start();
    }
}
//结果:
//小关-->学习Java
//小梁-->学习Python
//小关-->学习Java
//小梁-->学习Python
//小关-->学习Java
//小梁-->学习Python
//小关-->学习Java
//小梁-->学习Python
//小关-->学习Java
//小梁-->学习Python

The above procedure solves the problems of data misalignment, repeated data removal and repeated setting.

Tip:
The difference between sleep () and wait ():
1.sleep () is a static method defined by the Thread class, which means that the thread sleeps and will give the execution opportunity to other threads, but the monitoring state is still maintained and will automatically resume;
2.wait ( ) Is a method defined by the Object class, which means that the thread waits until the notify () or notifyAll () is executed.

发布了49 篇原创文章 · 获赞 25 · 访问量 1519

Guess you like

Origin blog.csdn.net/weixin_45784666/article/details/105067987