美文网首页
java笔记--线程间通信

java笔记--线程间通信

作者: 吃饱喝足搬代码丶 | 来源:发表于2018-04-10 23:38 被阅读0次

线程间通讯:

多个线程在处理同一资源,但是任务却不同 。

比如对于同一个资源,一边在输入,一边在输出:

class Resource{
    String name;
    String sex;
}
//输入
class Input implements Runnable{
    Resource r;
    Input(Resource r){
        this.r=r;
    }
    public void run(){
        int x=0;
        while(true){
            synchronized(r){//因为Resource是共同操作的,所以r可以作为锁
                if(x==0){
                    r.name="mike";
                    r.sex="nan";
                }else{
                    r.name="丽丽";
                    r.sex="女女女女";
                }
                x=(x+1)%2;
            }
        }
    }
}
//输出
class Output implements Runnable{
    Resource r;
    Output(Resource r){
        this.r=r;
    }
    public void run(){
        while(true){
            synchronized(r){
                System.out.print(r.name+"..."+r.sex);
            }
        }
    }
}

public class TongXun {

    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();
    }
}
运行:

等待唤醒机制:

涉及的方法:

1 wait():让线程处于冻结状态,被wait的线程会被存储到线程池当中。
2 notify():唤醒线程池中的任意一个线程。
3 notifyAll():唤醒线程池中的所有线程

这些方法都必须定义在同步中。
因为这些方法是用于操作线程状态的方法。
必须要明确到底操作得是哪个锁上的线程。

class Resource{
    String name;
    String sex;
    boolean flag=false;
}
//输入
class Input implements Runnable{
    Resource r;
    Input(Resource r){
        this.r=r;
    }
    public void run(){
        int x=0;
        while(true){
            synchronized(r){//因为Resource是共同操作的,所以r可以作为锁
                if(r.flag)
                    try{
                        r.wait();
                        }catch(InterruptedException e){ 
                        }
                if(x==0){
                    r.name="mike";
                    r.sex="nan";
                }else{
                    r.name="丽丽";
                    r.sex="女女女女";
                }
                r.flag=true;
                r.notify();
            }
            x=(x+1)%2;
        }
    }
}
//输出
class Output implements Runnable{
    Resource r;
    Output(Resource r){
        this.r=r;
    }
    public void run(){
        while(true){
            synchronized(r){
                if(!r.flag)
                    try{
                        r.wait();
                        }catch(InterruptedException e){ 
                        }
                System.out.println(r.name+"..."+r.sex);
                r.flag=false;
                r.notify();
            }
        }
    }
}
public class NofityDemo {

    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();
    }
}
运行:

等待唤醒机制避免了成片的输出的现象,因为等待唤醒机制做的就是当一个资源被输入,资源被占有,只有先输出了才能再次输入资源

思考1:wait(),notify(),notifyAll(),用来操作线程为什么定义在了Object类中?
1 这些方法存在于同步中;
2 使用这些方法时必须要标识所属的同步的锁。
3 锁可以是任意对象,所以任意对象调用的方法一定定义在Object类中。

优化:

资源一般都是私有的,这里资源进行私有化,并对外提供方法。

class Resource{
    private String name;
    private String sex;
    private boolean flag=false;
    
    public synchronized void set(String name,String sex){
        if(flag)
            try{
                this.wait();
                }catch(InterruptedException e){ 
                }
        this.name=name;
        this.sex=sex;
        flag=true;
        this.notify();
    }
    public synchronized void Out(){
        if(!flag)
            try{
                this.wait();
                }catch(InterruptedException e){ 
                }
        System.out.println(name+"...优化..."+sex);
        flag=true;
        this.notify();
    }
}
//输入
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("mike","nan");
            }else{
                r.set("mike","nan");
                }
            x=(x+1)%2;
            }
            
        }
    }
//输出
class Output implements Runnable{
    Resource r;
    Output(Resource r){
        this.r=r;
    }
    public void run(){
        while(true){
            r.Out();
        }
    }
}
public class NofityDemo {

    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();
    }
}
运行:

思考2:wait(),sleep()有什么区别?
wait()释放执行权,释放锁;sleep()释放cpu执行权,不释放锁。

相关文章

  • java笔记--线程间通信

    线程间通讯: 多个线程在处理同一资源,但是任务却不同 。 比如对于同一个资源,一边在输入,一边在输出: 等待唤醒机...

  • 线程间通信剖析——Java进阶

    Java线程间通信剖析 本文将介绍常用的线程间通信工具CountDownLatch、CyclicBarrier和P...

  • 2.Java内存模型

    1.java并发编程的线程间通信及线程间如何同步线程间通信分为:共享内存,消息传递。线程间同步:共享内存是代码指定...

  • Java多线程(2)

    Java多线程(2) 线程间的通信 线程间的通信又称为进程内通信,多个线程实现互斥访问共享资源时会互相发送信号或等...

  • Java - 线程间通信

    涉及到的知识点:thread.join(), object.wait(), object.notify(), Co...

  • Java线程间通信

    涉及到多个线程协同完成某个任务的时候,就用到了线程间通信的相关知识点。这其中涉及到的知识点有:(1)thread....

  • Java 线程间通信

    线程间的交互和通信 一个线程启动另一个线程public static void main(String[] arg...

  • Java 线程间通信

    1. 线程之间如何通信 共享内存(隐式通信) 消息传递(显式通信 wait / notify synchroniz...

  • Java线程<第四篇>:线程间通信

    线程间通信是Java线程必须掌握的课程之一。线程间的通信的前提是,必须要保证线程还活着,可以使用阻塞方法,将线程暂...

  • Java多线程:线程间通信之volatile与sychroniz

    由前文Java内存模型我们熟悉了Java的内存工作模式和线程间的交互规范,本篇从应用层面讲解Java线程间通信。 ...

网友评论

      本文标题:java笔记--线程间通信

      本文链接:https://www.haomeiwen.com/subject/ktnwhftx.html