• Java学习之线程间通信(双线程)


    线程间通讯:多个线程在处理同一资源,但是任务不同

    练习一:双线程出现线程安全问题,需要使用同步,思考同步代码添加位置
    需求:银行账户存钱,显示谁在账户存钱了,存了多少钱
    分析:
    操作同一银行账户
    两个不同的操作,一个是存,一个是显示
    这个两个操作可以同时执行

    代码:

     1 class Bank
     2 {
     3     String name;//存钱人名
     4     int amount;
     5     
     6     //无论是存还是取应该都是银行的动作
     7     void put(String name,int amount)
     8     {
     9         this.name=name;
    10         this.amount=amount;
    11     }
    12     
    13     void take()
    14     {
    15         System.out.println(this.name+"---"+this.amount);
    16     }
    17 }
    18 //定义对象实现Runnable,设置线程任务
    19 class Input implements Runnable
    20 {
    21     private Bank b;
    22     //使用构造函数保证存钱和显示同一资源
    23     public Input(Bank b)
    24     {
    25         this.b=b;
    26     }
    27     public void run()
    28     {
    29         int x=0;
    30         while(true)
    31         {
    32             if(x==0)
    33             {
    34                 b.put("张三",100);
    35             }
    36             else
    37             {
    38                 b.put("lisi",200);
    39             }
    40             //0与1之间切换可使用求2的余数
    41             x=(x+1)%2;
    42         }
    43     }
    44 }
    45 
    46 //定义对象实现Runnable,设置线程任务
    47 class Output implements Runnable
    48 {
    49     private Bank b;
    50     //使用构造函数保证存钱和显示同一资源
    51     public Output(Bank b)
    52     {
    53         this.b=b;
    54     }
    55     public void run()
    56     {
    57         while(true)
    58         {
    59             b.take();
    60         }
    61     }
    62 }
    63 
    64 class ThreadDemo
    65 {
    66     public static void main (String[] args)
    67     {
    68         //同一资源
    69         Bank b=new Bank();
    70         
    71         Input in=new Input(b);
    72         Output out=new Output(b);
    73         
    74         //
    75         Thread t1=new Thread(in);
    76         Thread t2=new Thread(out);
    77         
    78         t1.start();
    79         t2.start();
    80     }
    81 }

    结果:

    出现线程安全,为什么呢?

    分析:

     解决方法:添加同步(synchronized),同步要添加到什么位置

    添加同步锁的原则:有共享数据被操作的代码上,且同步锁对象要相同(同步方法的同步锁为,此类的对象(this))

    代码:

     1 class Bank
     2 {
     3     String name;//存钱人名
     4     int amount;
     5     
     6     //同步方法的同步锁为,此类的对象(this)
     7     synchronized void put(String name,int amount)
     8     {
     9         this.name=name;
    10         this.amount=amount;
    11     }
    12     
    13     synchronized void take()
    14     {
    15         System.out.println(this.name+"---"+this.amount);
    16     }
    17 }

    结果出现的效果与预想结果不同,预想结果是存一笔,显示一笔

    结果分析:

     接下来,想法是:在t1中执行完成后就让t2执行

    具体做法:

    1、使用一个共享数据(flag)记录t1是否已执行

    2、已执行就让t1等待(原因:防止t1再次获取CPU执行权),让t2执行

    3、t2执行完成,t2等待,把t1设置成未执行状态(让t1获取CPU执行资格)

     1 class Bank
     2 {
     3     private String name;
     4     private int amount;
     5     private boolean flag=false;
     6     
     7     synchronized void put(String name,int amount)
     8     {
     9         //1、判断线程是否已执行,防止t1线程多次获取CUP执行权
    10         if(flag)
    11             try{this.wait();}catch(InterruptedException e){}//wait()方法,将线程存放在阻塞线程池中,释放CUP执行权和释放同步锁
    12             
    13         this.name=name;
    14         this.amount=amount;
    15         //已执行赋值
    16         this.flag = true;
    17         //唤醒阻塞线程池中的任意一个线程,获取CUP执行资格
    18         this.notify();
    19     }
    20     
    21     synchronized void take()
    22     {
    23         if(!flag)
    24             try{this.wait();}catch(InterruptedException e){}
    25         System.out.println(this.name+"---"+this.amount);
    26         
    27         this.flag = false;
    28         this.notify();
    29     }
    30 }

    结果:

  • 相关阅读:
    中文短文本分类
    词袋和词向量模型
    【NLP-2017-SA】翻译-Recurrent Attention Network on Memory for Aspect Sentiment Analysis(2017emnlp)
    过拟合和欠拟合问题总结
    【Docker-6】-Docker删除运行过的镜像
    【Docker-5】-Docker运行自己的镜像
    【Docker-3】-Docker入门命令解读
    【Docker-4】-Docker启动nginx
    【Docker-2】windows下安装docker
    【Docker-1】docker简介
  • 原文地址:https://www.cnblogs.com/WarBlog/p/12074056.html
Copyright © 2020-2023  润新知