zoukankan      html  css  js  c++  java
  • 多线程练习题

    多线程练习题

    编写程序实现,子线程循环3次,接着主线程循环5次,接着再子线程循环3次,主线程循环5次,如此反复,循环3次

    第一种实现方式:使用synchronized关键字


    package com.aaa.test;

    public class Test1 {

      private boolean flag=false;

    //   主线程要实现的功能
      public synchronized void mainFunction(){

          while (!flag){
              try {
                  this.wait();
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
          }
          for (int i=0;i<5;i++){
              System.out.println("mainFunction,主线程循环"+i+"次");
          }
          this.notify();
          flag=false;
      }

    //   子线程要实现的功能
      public synchronized void subFunction(){

          while (flag){
              try {
                  this.wait();
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
          }
          for (int i=0;i<3;i++){
              System.out.println("subFunction,子线程循环"+i+"次");
          }
          this.notify();
          flag=true;
      }

      public static void main(String[] args) {
          final Test1 t= new Test1();
    //       子线程循环三次
          new Thread(new Runnable() {

              public void run() {
                  for (int i=0;i<3;i++){
                      t.subFunction();
                      System.out.println("======");
                  }
              }
          }).start();

    //       主线程循环三次
          for (int i=0;i<3;i++){
              t.mainFunction();
              System.out.println("======");
          }
      }
    }

    第二种实现方式:使用 lock 锁和 Condition 接口


    package com.aaa.test;

    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;

    public class Test2 {
      private boolean flag = false;
      Lock lock = new ReentrantLock();
      Condition con = lock.newCondition();

    //   主线程要实现的功能
      public void mainFunction(){
          System.out.println("1.主线程开始"+" -- flag="+flag);
          lock.lock();
          try{
              while(!flag){
                  try {
                      System.out.println("2.主线程等待"+" -- flag="+flag);
                      con.await();
                      // 使当前线程加入 await() 等待队列中,并释放当锁,当其他线程调用signal()会重新请求锁。与Object.wait()类似。
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }
              }
              System.out.println("7.主线程开始循环5次"+" -- flag="+flag);
              for(int i=0;i<5;i++){
                  System.out.println("mainFunction"+i+" -- flag="+flag);
              }
              flag = false;
              System.out.println("8.唤醒子线程"+" -- flag="+flag);
              con.signal();
              // 唤醒一个在 await()等待队列中的线程。与Object.notify()相似
          }finally{
              lock.unlock();
          }
      }

      // 子线程要实现的功能
      public void subFunction(){
          System.out.println("3.子线程开始"+" -- flag="+flag);
          lock.lock();
          try{
              while(flag){
                  try {
                      System.out.println("6.子线程等待"+" -- flag="+flag);
                      con.await(); // 使当前线程加入 await() 等待队列中,并释放当锁,当其他线程调用signal()会重新请求锁。与Object.wait()类似。
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }
              }
              System.out.println("4.子线程开始循环3次"+" -- flag="+flag);
              for(int i=0;i<3;i++){
                  System.out.println("subFunction"+i+" -- flag="+flag);
              }
              flag = true;
              System.out.println("5.唤醒主线程"+" -- flag="+flag);
              con.signal(); // 唤醒一个在 await()等待队列中的线程。与Object.notify()相似
          }finally{
              lock.unlock();
          }
      }

      public static void main(String[] args) {
          final Test2 t= new Test2();
    //       子线程循环三次
          new Thread(new Runnable() {

              public void run() {
                  for (int i=0;i<3;i++){
                      t.subFunction();
                      System.out.println("======");
                  }
              }
          }).start();

    //       主线程循环三次
          for (int i=0;i<3;i++){
              t.mainFunction();
              System.out.println("======");
          }
      }
    }

    模拟多个人通过一个山洞的模拟,这个山洞每次只能通过一个人,每个人通过山洞的时间为5秒,随机生成10个人,同时准备过此山洞,显示以下每次通过山洞的人的姓名。

    package com.aaa.test;

    import java.util.LinkedHashSet;
    import java.util.Set;

    public class Test3 implements Runnable{
      private static int deng=0;
      @Override
      public void run() {
          deng= deng+50;

          try
          {
              Thread.sleep(deng);

          } catch (InterruptedException e)
          {

              e.printStackTrace();
          }

          System.out.println(Thread.currentThread().getName()
                  +" 过山洞");
      }

      public static void main(String[] args) {
          String ary[] ={"赵","钱","孙","李","周","吴","郑","王","冯","陈"};

          Test3 gsd = new Test3();

          Set<Integer> set=new LinkedHashSet<Integer>();
          while(true){
              if(set.size() == 10){
                  break;
              }

              //乱序排列(随机)
              int a=(int) (Math.random()*10);

              set.add(a);
          }
          for(int b:set){

              Thread th = new Thread(gsd, ary[b]);


              th.start();
          }
      }
    }
  • 相关阅读:
    WPF XAML之bing使用StringFormat
    C#程序以管理员权限运行
    注册表REG文件编写大全
    linux 的基本操作(编写shell 脚本)
    linux的基本操作(正则表达式)
    linux的基本操作(shell 脚本的基础知识)
    linux的基本操作(RPM包或者安装源码包)
    linux的基本操作(文件压缩与打包)
    linux的基本操作(文本编辑工具vim)
    linux的基本操作(磁盘管理)
  • 原文地址:https://www.cnblogs.com/nnnnmmmm/p/10998722.html
Copyright © 2011-2022 走看看