多线程-线程间通信

1.多线程-线程间通信-问题演示

多线程间通信:多个线程处理同一资源,但是处理动作却不同。

//创建一个资源描述。资源中有name sex。用于存储数据。
class Resource{
    String name;
    String sex;
}

//需要定义一个输入任务描述。既然是线程任务,必须实现Runnable接口。 
class Input implements Runnable{
    private Resource r;
    Input(Resource r){
        this.r = r;
    }
    //覆盖run方法。 
    public void run(){
        int x = 0;
        while(true){
         //输入任务中必然要处理资源。要给资源中的name sex赋值。
         //需要对象。对象确定吗?不确定,传递进来就哦了。输入任务一创建对象就必须有资源。
         //完全可以在构造时明确资源对象。 
            if(x==0){
                r.name = "zhangsan";
                r.sex = "man";
            }else{
                r.name = "小花";
                r.sex = "女女女女女";
            }
            //赋值后,将标记改为true,说明有值。
            x = (x+1)%2;
        }
    }
}
 
//需要定义一个输出任务描述。既然是线程任务,必须实现Runnable接口。 
class Output implements Runnable{
    private Resource r;
    Output(Resource r){
        this.r = r;
    }
    public void run(){
        while(true){
            System.out.println(r.name+"...."+r.sex);
        }
    }
}
class  ThreadDemo_Resource{
    public static void main(String[] args) {
        //1,创建资源的对象。
        Resource r = new Resource();
        //2,创建任务对象。
        Input in = new Input(r);
        Output out = new Output(r);
         
        //3,创建线程对象。
        Thread t1 = new Thread(in);
        Thread t2 = new Thread(out);
        //4,启动并运行线程。
        t1.start();
        t2.start();
    }
}

运行结果:

2.多线程-线程间通信-问题解决

使用同步代码块

class Resource{
    String name;
    String sex;
}

class Input implements Runnable{
    private Resource r;
    Input(Resource r){
        this.r = r;
    }
     
    public void run(){
        int x = 0;
        while(true){
            synchronized(r){        
                if(x==0){
                    r.name = "zhangsan";
                    r.sex = "man";
                }else{
                    r.name = "小花";
                    r.sex = "女女女女女";
                }
            }
            x = (x+1)%2;  
        }
    }
}
 

class Output implements Runnable{
    private Resource r;
    Output(Resource r){
        this.r = r;
    }
    public void run(){
        while(true){
            synchronized(r){
                System.out.println(r.name+"...."+r.sex);
            }
        }
    }
}
class  ThreadDemo_Resource{
    public static void main(String[] args) {
        //1,创建资源的对象。
        Resource r = new Resource();
        //2,创建任务对象。
        Input in = new Input(r);
        Output out = new Output(r);
         
        //3,创建线程对象。
        Thread t1 = new Thread(in);
        Thread t2 = new Thread(out);
        //4,启动并运行线程。
        t1.start();
        t2.start();
    }
}

3.多线程-线程间通信-等待唤醒机制

wait():可以让当前处于等待,这时的线程被临时存储到的线程池中。

notify():唤醒线程池中任意一个等待的线程。

notifyAll():唤醒线程池中所有的等待线程。

这些方法在使用时,必须要定义在同步中,必须被所属同步的锁对象来调用。

//创建一个资源描述。资源中有name sex。用于存储数据。
class Resource{
    String name;
    String sex;
    //定义标记,用于判断资源中是否有数据。
    boolean flag;//默认值为false
}
 
 
//需要定义一个输入任务描述。
class Input implements Runnable{
    private Resource r;
    Input(Resource r){
        this.r = r;
    }
    
    public void run(){
        int x = 0;
        while(true){
            synchronized(r){ 
                if(r.flag){//flag为false不执行wait语句
                    try{r.wait();}catch(Exception e){}}
                if(x==0){
                    r.name = "zhangsan";
                    r.sex = "man";
                }else{
                    r.name = "小花";
                    r.sex = "女女女女女";
                }
                //赋值后,将标记改为true,说明有值啦。
                r.flag = true;
                //唤醒等待的线程。
                r.notify();
            }
            x = (x+1)%2; 
        }
    }
}
 
//需要定义一个输出任务描述。 
class Output implements Runnable{
    private Resource r;
        Output(Resource r){
        this.r = r;
    }
    public void run(){
        while(true){
            synchronized(r){
                if(!r.flag){//资源中没有数据就等待。
                    try{r.wait();}catch(Exception e){}}
                System.out.println(r.name+"...."+r.sex);
                //将标记改为false.
                r.flag = false;
                r.notify();//唤醒等待的线程。其实就是唤醒了输入线程。 
            }
        }
    }
}
 
 
class  ThreadDemo_Resource{
    public static void main(String[] args) {
        //1,创建资源的对象。
        Resource r = new Resource();
        //2,创建任务对象。
        Input in = new Input(r);
        Output out = new Output(r);
         
        //3,创建线程对象。
        Thread t1 = new Thread(in);
        Thread t2 = new Thread(out);
        //4,启动并运行线程。
        t1.start();
        t2.start();
    }
}

运行结果

4.多线程-线程间通信-代码优化

//资源描述
class Resource{
    private String name;
    private String sex;
    //定义标记,用于判断资源中是否有数据。
    private boolean flag;
     
    //对外提供方法访问这些属性。
    public synchronized void set(String name,String sex){
        if(flag)//flag为false,输入任务不等待
            try{this.wait();}catch(Exception e){}
         
        this.name = name;
        this.sex = sex;
        flag = true;
        this.notify();
    }
     
    //对外提供获取方法。
    public synchronized void out(){
        if(!flag)//falg为false,输出任务等待
            try{this.wait();}catch(Exception e){}
        System.out.println(name+"::::"+sex);
        flag = false;
        this.notify();
    }
}
 
 
//需要定义一个输入任务描述。 
    class Input implements Runnable{
        private Resource r;
        Input(Resource r){
            this.r = r;
        }
        //覆盖run方法。 
        public void run(){
            int x = 0;
            while(true){
                if(x==0){
                    r.set("zhangsan","man");
                }else{
                    r.set("小花","女女女女女");
                }
                x = (x+1)%2;
            }
        }
    }

 
//需要定义一个输出任务描述。 
class Output implements Runnable{
    private Resource r;
    Output(Resource r){
        this.r = r;
    }
    public void run(){
        while(true){
            r.out();
        }
    }
}
 
 
 
class  ThreadDemo2_Resource{
    public static void main(String[] args) {
        //1,创建资源的对象。
        Resource r = new Resource();
        //2,创建任务对象。
        Input in = new Input(r);
        Output out = new Output(r);
         
        //3,创建线程对象。
        Thread t1 = new Thread(in);
        Thread t2 = new Thread(out);
        //4,启动并运行线程。
        t1.start();
        t2.start();
    }
}

5.多线程-线程间通信-单生产者单消费者示例

/*
单生产者和单消费者。等待唤醒机制。
*/
//资源
class Resource{
    private String name;//定义一个商品都有名字。
    private int count = 1;//定义一个商品的编号。
    private boolean flag = false;//定义用来判断是否有商品的标记。
    
    public synchronized  void set(String name){
        if(flag)//flag为false,生成任务不等待
            try{wait();}catch(Exception e){}
        this.name = name+"--"+count;
        count++;
        System.out.println(Thread.currentThread().getName()+"---生产了,"+this.name);
        
        flag = true;//将标记改为true。
        notify();//唤醒等待的线程。 
    }
     
    public synchronized void get(){
        if(!flag)//flag为false,消费任务等待
            try{wait();}catch(Exception e){}
        System.out.println(Thread.currentThread().getName()+"-------消费了....."+this.name);
        flag = false;
        notify();
    }
}
 
 
//定义生产者的任务。
class Producer implements Runnable{
    private Resource r;
    Producer(Resource r){
        this.r = r;
    }
    public void run(){
        while(true){
            r.set("蛋糕");
        }
    } 
}
 
 
//定义消费者的任务。
class Consumer implements Runnable{
    private Resource r;
    Consumer(Resource r){
        this.r = r;
    }
    public void run(){
        while(true){
            r.get();
        }
    }
}
 
 
class ThreadDemo_Producer_Consumer {
    public static void main(String[] args) {
        Resource r = new Resource();
        Producer pro = new Producer(r);
        Consumer con = new Consumer(r);
        Thread t1 = new Thread(pro);
        Thread t2 = new Thread(con);
        t1.start();
        t2.start();
    }
}

单生产单消费,等待和唤醒的始终只有一个线程,没有问题。

时间: 2024-11-06 12:53:59

多线程-线程间通信的相关文章

多线程-线程间通信-多生产者多消费者示例

1.多线程-线程间通信-多生产者多消费者问题 多生产者和多消费者.等待唤醒机制. 产生了两个问题: 1.出现了多次连续生产,未消费,或者一个商品被消费多次. 解决:必须要--------每一个被唤醒的线程判断一次标记,所以将if判断改为while判断. 2.出现了死锁. 本方唤醒了本方,导致了所有的线程都等待了. 解决方式就是:唤醒所有等待的线程.这样既唤醒了本方也唤醒对方. 虽然解决了多生产消费的问题,但是有些低效. 解决方法一: 唤醒所有等待的线程 class Resource{     p

java多线程——线程间通信之线程等待唤醒机制

三个方法 wait() notify() notifyAll() 三个方法都使用在同步中,因为要对持有锁(又叫监控)的线程操作. 所以要使用在同步中,因为只有同步才具有锁. 为什么这些操作线程的方法均出现在Object类中? 因为这些方法在操作同步中的线程时候,都必须要标识所操作线程识有锁.只有同一个锁上的被等待的线程,可以被同一个锁上的notify唤醒,不可以对不同锁中的线程进行唤醒. 也就是说,等待和唤醒必须是同一个锁. public class Demo1 { public static

【黑马】程序员————多线程(二)单例设计模式、线程间通信,JDK1.5互斥锁

------Java培训.Android培训.iOS培训..Net培训.期待与您交流!----- 一.单例设计模式 单例设计模式的意义: A.保证类在内存中只有一个对象,不提供外部访问方式,构造函数用private修饰. B.提供公共方法(static修饰,类的静态方法),获取类的实例.单例设计模式分为饿汉和懒汉两种模式. 饿汉式&懒汉式 class Test33 { public static void main(String[] args) { Fanjianan.getInstance()

黑马程序员——JAVA基础之Day24 多线程 ,死锁,线程间通信 ,线程组,线程池,定时器。

------- android培训.java培训.期待与您交流! ---------- Lock()实现提供了比使用synchronized方法和语句可获得更广泛的锁定操作. private Lock lock =new ReentrantLock(); 被锁的代码要用   lock.lock()                lock.unlock()    包括.其中用try   ...finally包围 同步:效率低,如果出现同步嵌套,会出现死锁.  但是安全. 死锁问题:两个或者两个以上

iOS中多线程_05_线程间通信NSThread/GCD

1.什么叫做线程间通信 在1个进程中,线程往往不是孤立存在的,多个线程之间需要经常进行通信 2.线程间通信的体现 1个线程传递数据给另1个线程 在1个线程中执行完特定任务后,转到另1个线程继续执行任务 3.线程间通信示例 UIImageView下载图片这个例子, 主线程中开启一个子线程去下载图片, 当图片下载完成之后再回到主线程中更新显示图片, 这样的一个过程就是线程间通信的一个过程. 4.NSThread线程间通信常用方法 // 第一种- (void)performSelectorOnMain

java多线程系列5-死锁与线程间通信

这篇文章介绍java死锁机制和线程间通信 死锁 死锁:两个或两个以上的线程在争夺资源的过程中,发生的一种相互等待的现象. 同步代码块的嵌套案例 public class MyLock { // 创建两把锁对象 public static final Object objA = new Object(); public static final Object objB = new Object(); } public class DieLock extends Thread { private b

2016年4月24日_JAVA学习笔记_多线程三_线程间通信

1.毕老师第十四天内容,线程间的通信.大概是使用wait(),notify()等一系列函数来控制各个线程的CPU执行资格和执行权,通过合适的时机在各个线程当中切换来达到线程间通信的目的. 涉及到的方法: wait():让线程处于等待状态,被wait()的线程会被存储到线程池当中,直到被唤醒.只能在同步方法中被调用. notify():随机选择一个在该对象上调用wait方法的线程,解除其阻塞状态.只能在同步方法和同步代码块中被调用. notifyAll():接触所有在该对象上调用wait()方法的

多线程学习笔记四--------------线程间通信问题

线程间通信问题: 多个线程在处理同一资源,但是任务却不同: java中将资源共享的方法(思路): 1.方法或者变量静态化---->静态化后,在类加载的时候,会将其加载到内存的方法区进行共享 2.单例设计模式---->保证只对一个实例进行操作. 3.将资源作为操作该资源的类的构造函数的参数,这样可以保证此类的多个对象在使用该资源的时候使用该资源的同一个实例. 现在我们要用第三种方法来进行线程间的通信. 情景:两个线程 ,一个负责输入,一个负责输出:共同处理一个资源. public class T

Java多线程 二 线程间通信

线程间通信: 多个线程在处理同一资源,但是 等待唤醒机制 涉及的方法: 1.wait() 让线程处于冻结状态,被wait的线程会被存储到线程池中. 2.notify() 唤醒线程池中的一个线程(任意) 3.notifyAll() 唤醒线程池中的所有线程.. 这些方法都必须定义在同步中, 因为这些方法是用于操作线程状态的方法. 必须明确到底操作的那个锁上的线程. 为什么操作线程的方法wait notify notifyAll定义在了Object中. 因为这些方法是监视器方法,监视器其实就是锁. 锁