• 多线程进阶之等待唤醒机制


    /*
     * 线程间通讯实例
     * 多个线程在处理同一资源,但是任务不同
     */
    
    //资源
    class Resource
    {
        String name;
        String sex;
    }
    //输入
    class Input implements Runnable
    {   
        Resource r;//类对象
        public Input(Resource r)//类对象做构造参数-->初始化资源
        {
            this.r=r;
        }
        public void run()
        {
            int x=0;
            while(true)
            {   
                /*
                 * 加上同步锁,因为输入输出任务共享资源,所以将资源对象r作为锁
                 * 也是为了让输入输出处于同一同步锁中,这样输入就不会在输入姓名林玲还没有赋值完性别女
                 * 时(周俊明被林玲覆盖),切换执行权
                 */
                synchronized(r) 
                {
                if(x==0)
                  {
                    r.name="周俊明";
                    r.sex="男";
                   }
                    else
                    {
                        r.name="林玲";
                        r.sex="女";
                    }
                }
                
                x=(x+1)%2;//算法切换:不断由if和else切换
            }
        }
    }
    //输出
    class Output implements Runnable
    {
        Resource r;
        public 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);
        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():唤醒线程池中的索引线程.
     * 
     * 这些方法都必须定义在同步中
     * 因为这些方法是用于操作线程状态的方法
     * 必须要明确到底操作的是哪个锁上的线程
     * 
     * 为什么操作线程的方法wait notify notifyAll定义在Object类中
     * 
     * 因为这些方法是监视器的方法.监视器就是锁
     * 锁可以是任意的对象,任意的对象调用的方式一定定义在object类中
     *  */
    //资源
    class Resour
    {
        String name;
        String sex;
        boolean flag=false;//标记
    }
    //输入
    class Inputs implements Runnable
    {   
        Resour r;//类对象
        public Inputs(Resour r)//类对象做构造参数-->初始化资源
        {
            this.r=r;
        }
        public void run()
        {
            int x=0;
            while(true)
            {   
                /*
                 * 加上同步锁,因为输入输出任务共享资源,所以将资源对象r作为锁
                 * 也是为了让输入输出处于同一同步锁中,这样输入就不会在输入姓名林玲还没有赋值完性别女
                 * 时(周俊明被林玲覆盖),切换执行权
                 */
                synchronized(r) 
                {
                    try {
                        if(r.flag)
                            r.wait(); //标明睡眠/唤醒同一锁上线程
                    } catch (InterruptedException e) {
                        // TODO: handle exception
                    }
                if(x==0)
                  {
                    r.name="周俊明";
                    r.sex="男";
                   }
                    else
                    {
                        r.name="林玲";
                        r.sex="女";
                    }
                r.flag=true;
                r.notify();
                }
                
                x=(x+1)%2;//算法切换:不断由if和else切换
            }
        }
    }
    //输出
    class Outputs implements Runnable
    {
        Resour r;
        public Outputs(Resour r)
        {
            this.r=r;
        }
        public void run() 
        {
            while(true)
            {
                synchronized(r)
                {
                    try {
                        if(!r.flag)
                            r.wait(); 
                    } catch (InterruptedException e) {
                        
                    }
                System.out.println(r.name+"....."+r.sex);
                r.flag=false;
                r.notify();
                }
            }
        }
    }
    public class ResourceDemo1 {
    public static void main(String[] args) {
        //创建资源
        Resour r=new Resour();
        //创建任务
        Inputs in=new Inputs(r);
        Outputs out=new Outputs(r);
        //创建线程
        Thread t1=new Thread(in);
        Thread t2=new Thread(out); 
        
        t1.start();
        t2.start(); 
    }
    }

    优化:

    //资源
    class Resours
    {
        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=false;
            this.notify();
        }
    }
    //输入
    class Inputce implements Runnable
    {   
        Resours r;//类对象
        public Inputce(Resours r)//类对象做构造参数-->初始化资源
        {
            this.r=r;
        }
        public void run()
        {
            int x=0;
            while(true)
            {   
                /*
                 * 加上同步锁,因为输入输出任务共享资源,所以将资源对象r作为锁
                 * 也是为了让输入输出处于同一同步锁中,这样输入就不会在输入姓名林玲还没有赋值完性别女
                 * 时(周俊明被林玲覆盖),切换执行权
                 */
                if(x==0)
                  {
                    r.set("周俊明","男");
                  }
                    else
                    {
                        r.set("林玲","女");
                     }
                 x=(x+1)%2;//算法切换:不断由if和else切换
                 }            
            }
        }
    //输出
    class Outputce implements Runnable
    {
        Resours r;
        public Outputce(Resours r)
        {
            this.r=r;
        }
        public void run() 
        {
            while(true)
            {
                r.out();
            }
        }
    }
    public class ResourceDemo2 {
    public static void main(String[] args) {
        //创建资源
        Resours r=new Resours();
        //创建任务
        Inputce in=new Inputce(r);
        Outputce out=new Outputce(r);
        //创建线程
        Thread t1=new Thread(in);
        Thread t2=new Thread(out); 
        
        t1.start();
        t2.start(); 
    }
    }

    一不小心就暴露了真实姓名

  • 相关阅读:
    SignalR学习笔记(一) 简单聊天室
    纽约工作日志流水账 Day 2
    纽约工作日志流水账 Day 1
    开放计算平台——数据仓库(Hive)权限控制
    SQL Standard Based Hive Authorization(基于SQL标准的Hive授权)
    jmap(Memory Map For Java)
    Hadoop CombineFileInputFormat实现原理及源码分析
    HiveServer连接优化
    Hive SQL运行状态监控(HiveSQLMonitor)
    jstack(Stack Trace for Java)
  • 原文地址:https://www.cnblogs.com/zjm1999/p/9969707.html
Copyright © 2020-2023  润新知