传智播客旗下技术交流社区北京校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 不太想网名 初级黑马   /  2019-5-13 14:47  /  185 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 小石姐姐 于 2019-5-17 11:19 编辑

.线程同步2.1卖票【应用】
  • 案例需求
    某电影院目前正在上映国产大片,共有100张票,而它有3个窗口卖票,请设计一个程序模拟该电影院卖票
  • 实现步骤

    • 定义一个类SellTicket实现Runnable接口,里面定义一个成员变量:private int tickets = 100;
    • 在SellTicket类中重写run()方法实现卖票,代码步骤如下
    • 判断票数大于0,就卖票,并告知是哪个窗口卖的
    • 卖了票之后,总票数要减1
    • 票没有了,也可能有人来问,所以这里用死循环让卖票的动作一直执行
    • 定义一个测试类SellTicketDemo,里面有main方法,代码步骤如下
    • 创建SellTicket类的对象
    • 创建三个Thread类的对象,把SellTicket对象作为构造方法的参数,并给出对应的窗口名称
    • [Java] 纯文本查看 复制代码
      public class SellTicket implements Runnable {
          private int tickets = 100;
          //在SellTicket类中重写run()方法实现卖票,代码步骤如下
          @Override
          public void run() {
              while (true) {
                  if (tickets > 0) {
                      System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "张票");
                      tickets--;
                  }
              }
          }
      }
      public class SellTicketDemo {
          public static void main(String[] args) {
              //创建SellTicket类的对象
              SellTicket st = new SellTicket();        //创建三个Thread类的对象,把SellTicket对象作为构造方法的参数,并给出对应的窗口名称
              Thread t1 = new Thread(st,"窗口1");
              Thread t2 = new Thread(st,"窗口2");
              Thread t3 = new Thread(st,"窗口3");        //启动线程
              t1.start();
              t2.start();
              t3.start();
          }
      }
      3同步代码块解决数据安全问题【应用】
      • 安全问题出现的条件

        • 是多线程环境
        • 有共享数据
        • 有多条语句操作共享数据

      • 如何解决多线程安全问题呢?

        • 基本思想:让程序没有安全问题的环境

      • 怎么实现呢?

        • 把多条语句操作共享数据的代码给锁起来,让任意时刻只能有一个线程执行即可
        • Java提供了同步代码块的方式来解决

      • 同步代码块格式:

        synchronized(任意对象) {
            多条语句操作共享数据的代码
        }
        synchronized(任意对象):就相当于给代码加锁了,任意对象就可以看成是一把锁
      • 同步的好处和弊端  

        • 好处:解决了多线程的数据安全问题
        • 弊端:当线程很多时,因为每个线程都会去判断同步上的锁,这是很耗费资源的,无形中会降低程序的运行效率


      • [AppleScript] 纯文本查看 复制代码
        代码演示public class SellTicket implements Runnable {
            private int tickets = 100;
            private Object obj = new Object();    @Override
            public void run() {
                while (true) {
                    //tickets = 100;
                    //t1,t2,t3
                    //假设t1抢到了CPU的执行权
                    //假设t2抢到了CPU的执行权
                    synchronized (obj) {
                        //t1进来后,就会把这段代码给锁起来
                        if (tickets > 0) {
                            try {
                                Thread.sleep(100);
                                //t1休息100毫秒
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                            //窗口1正在出售第100张票
                            System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "张票");
                            tickets--; //tickets = 99;
                        }
                    }
                    //t1出来了,这段代码的锁就被释放了
                }
            }
        }public class SellTicketDemo {
            public static void main(String[] args) {
                SellTicket st = new SellTicket();        Thread t1 = new Thread(st, "窗口1");
                Thread t2 = new Thread(st, "窗口2");
                Thread t3 = new Thread(st, "窗口3");        t1.start();
                t2.start();
                t3.start();
            }
        }
        5TCP通信程序练习【应用】
        • 案例需求
          客户端:数据来自于键盘录入,直到输入的数据是886,发送数据结束
          服务端:接受到的数据写入文本文件中
        • 案例分析

          • 客户端创建对象,使用键盘录入循环接受数据,接受一行发送一行,直到键盘录入886为止
          • 服务端创建对象,创建输出流对象指向文件,每接受一行数据后使用输出流输出到文件中,直到接受到null为止

        • 代码实现

        [AppleScript] 纯文本查看 复制代码
        ublic class ClientDemo {
            public static void main(String[] args) throws IOException {
                //创建客户端Socket对象
                Socket s = new Socket("192.168.1.66",10000);
                //数据来自于键盘录入,直到输入的数据是886,发送数据结束
                BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
                //封装输出流对象
                BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
                String line;
                while ((line=br.readLine())!=null) {
                    if("886".equals(line)) {
                        break;
                    }
                    bw.write(line);
                    bw.newLine();
                    bw.flush();
                }
                //释放资源
                s.close();
            }
        }
        public class ServerDemo {
            public static void main(String[] args) throws IOException {
                //创建服务器Socket对象
                ServerSocket ss = new ServerSocket(10000);
                //监听客户端连接,返回一个对应的Socket对象
                Socket s = ss.accept();
                //接收数据
                BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
                //把数据写入文本文件
                BufferedWriter bw = new BufferedWriter(new FileWriter("myNet\\s.txt"));
                String line;
                while ((line=br.readLine())!=null) {
                    bw.write(line);
                    bw.newLine();
                    bw.flush();
                }
                //释放资源
                bw.close();
                ss.close();
            }
        }
        





分享至 : QQ空间
收藏

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马