首页 > 编程语言 > 详细

JAVA学习(线程间通信:共享内存,等待唤醒;)

时间:2021-04-01 22:43:14      阅读:14      评论:0      收藏:0      [点我收藏+]

一、线程间通信

    如果每个线程间都孤立的运行,那就会造资源浪费。所以在现实中,我们需要这些线程间可以按照指定的规则共同完成一件任务,所以这些线程之间就需要互相协调,这个过程被称为线程的通信。

线程通信就是当多个线程共同操作共享的资源时,互相告知自己的状态以避免资源争夺。

 

线程间通讯的方式: (存在多种方式,这里只写了共享内存,等待唤醒)
1.共享内存:

  使用这种方式进行线程通信,通常会设置一个共享变量。然后多个线程去操作同一个共享变量。从而达到线程通讯的目的。同时在多个线程操作同一个资源的过程中,必须要考虑的是共享变量的同步问题,这也共享内存容易出错的原因所在。

  在这种通讯模型中,不同的线程之间是没有直接联系的。都是通过共享变量这个“中间人”来进行交互。而这个“中间人”必要情况下还需被保护在临界区内(加锁或同步)。由此可见,一旦共享变量变得多起来,并且涉及到多种不同线程对象的交互,这种管理会变得非常复杂,极容易出现死锁等问题。

例如:设置一个共享资源Resoure类,Input类用来输入信息,Output用来提取信息,ResourceDemo类用来调用执行,

public class Resource {
    String name;
    String sex;
}


public class Input implements Runnable{
    Resource r;
    Input(Resource r){
        this.r = r;
    }
    public void run(){
        int x = 0;
        while(true)
            synchronized (r) {        //Input与Output共用一个锁r
                if (x == 0) {
                    r.name = "小明";
                    r.sex = "男";
                } else {
                    r.name = "小红";
                    r.sex = "女";
                }
            }
            x = (x + 1) % 2;
        }

    }

}


public class Output implements Runnable{
    Resource r;
    Output(Resource r){
        this.r = r;
    }
    public void run(){
        while(true) {
            synchronized (r) {
                System.out.println(r.name + "...." + r.sex);
            }
        }
    }
}

public class ResourceDemo {
    public static void main(String[] args) {
        Resource r = new Resource();
        Input in = new Input(r);      //将对象r作为参数传递,Input,Output共用一个锁
        Output out = new Output(r);

        Thread t1 = new Thread(in);
        Thread t2 = new Thread(out);
        t1.start();
        t2.start();
    }
}

 

2.等待唤醒机制:

涉及的方法:

<1>wait();  让线程处于冻结状态,被wait的线程会被存储到线程池中。

<2>notify();  唤醒线程池中的一个线程(任意)

<3>notifyAll(); 唤醒线程池中的所有线程。

 这些方法都必须定义在同步中,因为这些方法是用于操作线程的方法。

必须要明确到底操作的是那个锁上的线程。

例如:

public class Resource {
    private String name;
    private String sex;
    private boolean flag = false;
    public synchronized void set(String name,String sex){
        if(flag)        //flag为真时,信息以及输入,需要被读取,所以输入进程等待
            try{this.wait();}catch(InterruptedException e){}
        this.name = name;
        this.sex = sex;
        flag = true;
        this.notify();  //输出进程被唤醒
    }
    public synchronized void out(){
        if(!flag)          //flag为假时,信息已经输出,需要再次输入,输出进程等待
            try{this.wait();}catch(InterruptedException e){}
        System.out.println(name+"...."+sex);
        flag = false;
        this.notify();    //输入进程被唤醒
    }

}


public class Input implements Runnable{
    Resource r;
    Input(Resource r){
        this.r = r;
    }
    public void run(){
        int x = 0;
        while(true){
            if (x == 0) {
                r.set("小明","男");
            }
            else {
                r.set("小红","女");
            }
            x = (x + 1) % 2;
        }
    }
}

public class Output implements Runnable{
    Resource r;
    Output(Resource r){
        this.r = r;
    }
    public void run(){
        while(true) {
            r.out();
            }
        }
    }

public class ResourceDemo {
    public static void main(String[] args) {
        Resource r = new Resource();
        Input in = new Input(r);
        Output out = new Output(r);

        Thread t1 = new Thread(in);
        Thread t2 = new Thread(out);
        t1.start();
        t2.start();
    }
}

 

JAVA学习(线程间通信:共享内存,等待唤醒;)

原文:https://www.cnblogs.com/gmangofight/p/14606777.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!