zoukankan      html  css  js  c++  java
  • 201772020113 李清华《面向对象程序设计(java)》第17周学习总结

     

    1、实验目的与要求

    (1) 掌握线程同步的概念及实现技术;

    (2) 线程综合编程练习

    2、实验内容和步骤

    实验1:测试程序并进行代码注释。

    测试程序1:

    l  在Elipse环境下调试教材651页程序14-7,结合程序运行结果理解程序;

    l  掌握利用锁对象和条件对象实现的多线程同步技术。

     1 package synch;
     2 
     3 import java.util.*;
     4 import java.util.concurrent.locks.*;
     5 
     6 /**
     7  * A bank with a number of bank accounts that uses locks for serializing access.
     8  * @version 1.30 2004-08-01
     9  * @author Cay Horstmann
    10  */
    11 public class Bank
    12 {
    13    private final double[] accounts;//银行的基本数据
    14    private Lock bankLock;//锁对象
    15    private Condition sufficientFunds;
    16 
    17    /**
    18     * Constructs the bank.
    19     * @param n the number of accounts
    20     * @param initialBalance the initial balance for each account
    21     */
    22    public Bank(int n, double initialBalance)
    23    {
    24       accounts = new double[n];
    25       Arrays.fill(accounts, initialBalance);
    26       bankLock = new ReentrantLock();
    27       sufficientFunds = bankLock.newCondition();
    28    }
    29 
    30    /**
    31     * Transfers money from one account to another.
    32     * @param from the account to transfer from
    33     * @param to the account to transfer to
    34     * @param amount the amount to transfer
    35     */
    36    public void transfer(int from, int to, double amount) throws InterruptedException
    37    {
    38       bankLock.lock();
    39       try
    40       {  //锁对象的引用条件对象
    41          while (accounts[from] < amount)
    42             sufficientFunds.await();
    43          System.out.print(Thread.currentThread());//打印出线程号
    44          accounts[from] -= amount;
    45          System.out.printf(" %10.2f from %d to %d", amount, from, to);
    46          accounts[to] += amount;
    47          System.out.printf(" Total Balance: %10.2f%n", getTotalBalance());
    48          sufficientFunds.signalAll();
    49       }
    50       finally
    51       {
    52          bankLock.unlock();
    53       }
    54    }
    55 
    56    /**
    57     * Gets the sum of all account balances.
    58     * @return the total balance
    59     */
    60    public double getTotalBalance()
    61    {
    62       bankLock.lock();//加锁
    63       try
    64       {
    65          double sum = 0;
    66 
    67          for (double a : accounts)
    68             sum += a;
    69 
    70          return sum;
    71       }
    72       finally
    73       {
    74          bankLock.unlock();//解锁
    75       }
    76    }
    77 
    78    /**
    79     * Gets the number of accounts in the bank.
    80     * @return the number of accounts
    81     */
    82    public int size()
    83    {
    84       return accounts.length;
    85    }
    86 }
    View Code
     1 package synch;
     2 
     3 /**
     4  * This program shows how multiple threads can safely access a data structure.
     5  * @version 1.31 2015-06-21
     6  * @author Cay Horstmann
     7  */
     8 public class SynchBankTest
     9 {
    10    public static final int NACCOUNTS = 100;
    11    public static final double INITIAL_BALANCE = 1000;
    12    public static final double MAX_AMOUNT = 1000;
    13    public static final int DELAY = 10;
    14    
    15    public static void main(String[] args)
    16    {
    17       Bank bank = new Bank(NACCOUNTS, INITIAL_BALANCE);
    18       for (int i = 0; i < NACCOUNTS; i++)
    19       {
    20          int fromAccount = i;
    21          Runnable r = () -> {
    22             try
    23             {
    24                while (true)
    25                {
    26                   int toAccount = (int) (bank.size() * Math.random());
    27                   double amount = MAX_AMOUNT * Math.random();
    28                   bank.transfer(fromAccount, toAccount, amount);
    29                   Thread.sleep((int) (DELAY * Math.random()));
    30                }
    31             }
    32             catch (InterruptedException e)
    33             {
    34             }            
    35          };
    36          Thread t = new Thread(r);
    37          t.start();
    38       }
    39    }
    40 }
    View Code

    测试程序2:

    l  在Elipse环境下调试教材655页程序14-8,结合程序运行结果理解程序;

    l  掌握synchronized在多线程同步中的应用。

     1 package synch2;
     2 
     3 /**
     4  * 这个程序显示了多个线程如何安全地访问数据结构,使用同步方法。
     5  * @version 1.31 2015-06-21
     6  * @author Cay Horstmann
     7  */
     8 public class SynchBankTest2
     9 {
    10    public static final int NACCOUNTS = 100;
    11    public static final double INITIAL_BALANCE = 1000;
    12    public static final double MAX_AMOUNT = 1000;
    13    public static final int DELAY = 10;
    14 
    15    public static void main(String[] args)
    16    {
    17       Bank bank = new Bank(NACCOUNTS, INITIAL_BALANCE);
    18       for (int i = 0; i < NACCOUNTS; i++)
    19       {
    20          int fromAccount = i;
    21          Runnable r = () -> {
    22             try
    23             {
    24                while (true)
    25                {
    26                   int toAccount = (int) (bank.size() * Math.random());
    27                   double amount = MAX_AMOUNT * Math.random();
    28                   bank.transfer(fromAccount, toAccount, amount);
    29                   Thread.sleep((int) (DELAY * Math.random()));
    30                }
    31             }
    32             catch (InterruptedException e)
    33             {
    34             }
    35          };
    36          Thread t = new Thread(r);
    37          t.start();
    38       }
    39    }
    40 }
    View Code
     1 package synch2;
     2 
     3 import java.util.*;
     4 
     5 /**
     6  * 具有多个使用同步原语的银行账户的银行。
     7  * @version 1.30 2004-08-01
     8  * @author Cay Horstmann
     9  */
    10 public class Bank
    11 {
    12    private final double[] accounts;
    13 
    14    /**
    15     * 建设银行。
    16     * @param n the number of accounts
    17     * @param initialBalance the initial balance for each account
    18     */
    19    public Bank(int n, double initialBalance)
    20    {
    21       accounts = new double[n];
    22       Arrays.fill(accounts, initialBalance);
    23    }
    24 
    25    /**
    26     * 把钱从一个账户转到另一个账户。
    27     * @param from the account to transfer from
    28     * @param to the account to transfer to
    29     * @param amount the amount to transfer
    30     */
    31    public synchronized void transfer(int from, int to, double amount) throws InterruptedException
    32    {
    33       while (accounts[from] < amount)
    34          wait();//导致线程进入等待状态直到它被通知。该方法只能在一个同步方法中调用。
    35       System.out.print(Thread.currentThread());//打印出线程号
    36       accounts[from] -= amount;
    37       System.out.printf(" %10.2f from %d to %d", amount, from, to);//第一个打印结果保留两位小数(最大范围是十位)
    38       accounts[to] += amount;
    39       System.out.printf(" Total Balance: %10.2f%n", getTotalBalance());
    40       notifyAll();//解除那些在该对象上调用wait方法的线程阻塞状态。该方法只能在同步方法或同步块内部调用。
    41    }
    42 
    43    /**
    44     * 获取所有帐户余额的总和。
    45     * @return the total balance
    46     */
    47    public synchronized double getTotalBalance()
    48    {
    49       double sum = 0;
    50 
    51       for (double a : accounts)
    52          sum += a;
    53 
    54       return sum;
    55    }
    56 
    57    /**
    58     * 获取银行中的帐户数量。
    59     * @return the number of accounts
    60     */
    61    public int size()
    62    {
    63       return accounts.length;
    64    }
    65 }
    View Code

    测试程序3:

    l  在Elipse环境下运行以下程序,结合程序运行结果分析程序存在问题;

    l  尝试解决程序中存在问题。

    class Cbank

    {

         private static int s=2000;

         public   static void sub(int m)

         {

               int temp=s;

               temp=temp-m;

              try {

                         Thread.sleep((int)(1000*Math.random()));

                       }

               catch (InterruptedException e)  {              }

              s=temp;

              System.out.println("s="+s);

                 }

    }

     

     

    class Customer extends Thread

    {

      public void run()

      {

       for( int i=1; i<=4; i++)

         Cbank.sub(100);

        }

     }

    public class Thread3

    {

     public static void main(String args[])

      {

       Customer customer1 = new Customer();

       Customer customer2 = new Customer();

       customer1.start();

       customer2.start();

      }

    }

    改进后:

     1 class Cbank {
     2     private static int s = 2000;
     3 
     4     public synchronized static void sub(int m) {
     5         int temp = s;
     6         temp = temp - m;
     7         try {
     8             Thread.sleep((int) (1000 * Math.random()));
     9         } catch (InterruptedException e) {
    10         }
    11         s = temp;
    12         System.out.println("s=" + s);
    13     }
    14 }
    15 
    16 class Customer extends Thread {
    17     public void run() {
    18         for (int i = 1; i <= 4; i++)
    19             Cbank.sub(100);
    20     }
    21 }
    22 
    23 public class Thread3 {
    24     public static void main(String args[]) {
    25         Customer customer1 = new Customer();
    26         Customer customer2 = new Customer();
    27         customer1.start();
    28         customer2.start();
    29     }
    30 }
    View Code

    实验2 编程练习

    利用多线程及同步方法,编写一个程序模拟火车票售票系统,共3个窗口,卖10张票,程序输出结果类似(程序输出不唯一,可以是其他类似结果)。

    Thread-0窗口售:第1张票

    Thread-0窗口售:第2张票

    Thread-1窗口售:第3张票

    Thread-2窗口售:第4张票

    Thread-2窗口售:第5张票

    Thread-1窗口售:第6张票

    Thread-0窗口售:第7张票

    Thread-2窗口售:第8张票

    Thread-1窗口售:第9张票

    Thread-0窗口售:第10张票

     1 public class Main {
     2     public static void main(String[] args) {
     3         Mythread mythread=new Mythread();
     4         Thread t1=new Thread(mythread);
     5         Thread t2=new Thread(mythread);
     6         Thread t3=new Thread(mythread);
     7         t1.start();
     8         t2.start();
     9         t3.start();
    10     }
    11 }
    12 class Mythread implements Runnable{
    13     int t=1;
    14     boolean flag=true;
    15     public void run() {
    16         while(flag) {
    17             try {
    18                 Thread.sleep(300);
    19             }catch(InterruptedException e) {
    20                 e.printStackTrace();
    21             }
    22             synchronized(this){
    23                 if(t<=10) {
    24                     System.out.println(Thread.currentThread().getName() + "窗口售:第" + t + "张票");
    25                     t++;
    26                 }
    27                 if(t>10) {
    28                     flag=false;
    29                 }
    30             }
    31         }
    32     }
    33 }
    View Code

    实验总结:本周实验学会了如何使用线程同步机制来解决多线程并发导致的不确定性。

  • 相关阅读:
    JavaScript-5(数组)
    JavaScript-作用域-预解析
    JavaScript-日历生成器
    JavaScript-8行5列表格
    package XXX.i386.rpm is not installed(检查在Linux上安装Oracle所需的pkg时)
    ubuntu13.04下安装jdk7
    Linux远程传输命令之scp使用方法
    Mac OS X中MacPorts安装和使用
    第一天 Linux 是什么
    Javascript与当前项目的思考
  • 原文地址:https://www.cnblogs.com/bmwb/p/10161625.html
Copyright © 2011-2022 走看看