zoukankan      html  css  js  c++  java
  • 201771010113 李婷华 《面向对象程序设计(Java)》第十七周总结

    一.理论知识部分

     Java 的线程调度采用优先级策略:优先级高的先执行,优先级低的后执行;多线程系统会自动为每个线程分配一个优先级,缺省时,继承其父类的优先级; 任务紧急的线程,其优先级较高; 同优先级的线程按“先进先出”的队列原则。

    调用setPriority(int a)重置当前线程的优先级,a取值可以是前述的三个静态量。调用getPriority()获得当前线程优先级。

    多线程并发运行不确定性问题解决方案:引入线程同步机制,使得另一线程要使用该方法,就只能等待。

    在Java中解决多线程同步问题的方法有两种:J ava SE 5.0中引入ReentrantLock类。 在共享内存的类方法前加synchronized修饰符。

    有关锁对象和条件对象的关键要点:锁用来保护代码片段,保证任何时刻只能有一个线程执行被保护的代码。锁管理试图进入被保护代码段的线程。锁可拥有一个或多个相关条件对象。每个条件对象管理那些已经进入被保护的代码 段但还不能运行的线程。

    synchronized关键字作用: 某个类内方法用synchronized 修饰后,该方法被称为同步方法;只要某个线程正在访问同步方法,其他线程欲要访问同步方法就被阻塞,直至线程从同 步方法返回前唤醒被阻塞线程,其他线程方可能进入同步方法。

    在同步方法中使用wait()、notify 和notifyAll()方法:一个线程在使用的同步方法中时,可能根据问题的需要,必须使用wait()方法使本线程等待,暂时让出CPU的使用权,并允许其它线程使用这个同步方法。线程如果用完同步方法,应当执行notifyAll()方 法通知所有由于使用这个同步方法而处于等待的线程结束等待。

    二.实验部分

    1、实验目的与要求

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

    (2) 线程综合编程练习

    2、实验内容和步骤

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

    测试程序1:

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

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

     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 }
    SynchBankTest
     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 }
    Bank

    测试程序2:

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

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

     1 package synch2;
     2 
     3 import java.util.*;
     4 
     5 /**
     6  * A bank with a number of bank accounts that uses synchronization primitives.
     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     * Constructs the bank.
    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     * Transfers money from one account to another.
    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    //使用synchronized修饰符
    32    public synchronized void transfer(int from, int to, double amount) throws InterruptedException
    33    {
    34       while (accounts[from] < amount)
    35          wait();//来自Object类
    36       System.out.print(Thread.currentThread());
    37       accounts[from] -= amount;
    38       System.out.printf(" %10.2f from %d to %d", amount, from, to);
    39       accounts[to] += amount;
    40       System.out.printf(" Total Balance: %10.2f%n", getTotalBalance());
    41       notifyAll();//解除所有线程的阻塞状态
    42    }
    43 
    44    /**
    45     * Gets the sum of all account balances.
    46     * @return the total balance
    47     */
    48    public synchronized double getTotalBalance()
    49    {
    50       double sum = 0;
    51 
    52       for (double a : accounts)
    53          sum += a;
    54 
    55       return sum;
    56    }
    57 
    58    /**
    59     * Gets the number of accounts in the bank.
    60     * @return the number of accounts
    61     */
    62    public int size()
    63    {
    64       return accounts.length;
    65    }
    66 }
    Bank

     

     1 package synch2;
     2 
     3 /**
     4  * This program shows how multiple threads can safely access a data structure,
     5  * using synchronized methods.
     6  * @version 1.31 2015-06-21
     7  * @author Cay Horstmann
     8  */
     9 public class SynchBankTest2
    10 {
    11    public static final int NACCOUNTS = 100;
    12    public static final double INITIAL_BALANCE = 1000;
    13    public static final double MAX_AMOUNT = 1000;
    14    public static final int DELAY = 10;
    15 
    16    public static void main(String[] args)
    17    {
    18       Bank bank = new Bank(NACCOUNTS, INITIAL_BALANCE);
    19       for (int i = 0; i < NACCOUNTS; i++)
    20       {
    21          int fromAccount = i;
    22          Runnable r = () -> {
    23             try
    24             {
    25                while (true)
    26                {
    27                   int toAccount = (int) (bank.size() * Math.random());
    28                   double amount = MAX_AMOUNT * Math.random();
    29                   bank.transfer(fromAccount, toAccount, amount);
    30                   Thread.sleep((int) (DELAY * Math.random()));
    31                }
    32             }
    33             catch (InterruptedException e)
    34             {
    35             }
    36          };
    37          Thread t = new Thread(r);
    38          t.start();
    39       }
    40    }
    41 }
    SynchBankTest2

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

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

    3.实验总结:

    本周的实验容量很少,实验也相对来说简单,完成的还算顺利。学长也教了我们常用的一些快捷键,本周的收获还是很大的。

     

  • 相关阅读:
    PHP和Redis实现在高并发下的抢购及秒杀功能示例详解
    quartz问题记录-missed their scheduled fire-time
    java(MyEclipse)创建webservice和测试webservice
    Redis wind7 安装
    spring boot新建项目报错总结
    spring boot新建项目启动报:Unregistering JMX-exposed beans on shutdown
    oracle安装过程和创建本地数据库
    正则表达式记录
    java continue与break区别
    Linux查看日志方法总结(1)
  • 原文地址:https://www.cnblogs.com/litinghua/p/10151751.html
Copyright © 2011-2022 走看看