zoukankan      html  css  js  c++  java
  • 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 }

    结果:

  • 相关阅读:
    cf1100 F. Ivan and Burgers
    cf 1033 D. Divisors
    LeetCode 17. 电话号码的字母组合
    LeetCode 491. 递增的子序列
    LeetCode 459.重复的子字符串
    LeetCode 504. 七进制数
    LeetCode 3.无重复字符的最长子串
    LeetCode 16.06. 最小差
    LeetCode 77. 组合
    LeetCode 611. 有效三角形个数
  • 原文地址:https://www.cnblogs.com/WarBlog/p/12074056.html
Copyright © 2011-2022 走看看