201771010101白玛次仁《2018面向对象程序设计(java)》第十七周学习总结(代码片段)

baimaciren baimaciren     2023-02-10     306

关键词:

实验十七  线程同步控制

实验时间 2018-12-10

1. 知识总结:

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

 Java中解决多线程同步问题的方法有两种:

- Java SE 5.0中引入ReentrantLock类。

- 在共享内存的类方法前加synchronized修饰符。

解决方案一:锁对象与条件对象:

ReentrantLock保护代码块的基本结构。

有关锁对象和条件对象的关键要点:

? 锁用来保护代码片段,保证任何时刻只能有一

个线程执行被保护的代码。

? 锁管理试图进入被保护代码段的线程。

? 锁可拥有一个或多个相关条件对象。

? 每个条件对象管理那些已经进入被保护的代码段但还不能运行的线程。

解决方案二: synchronized关键字。

synchronized关键字作用:

? 某个类内方法用synchronized 修饰后,该方法被称为同步方法;

? 只要某个线程正在访问同步方法,其他线程欲要访问同步方法就被阻塞,直至线程从同

步方法返回前唤醒被阻塞线程,其他线程方可能进入同步方法。

在同步方法中使用wait()notify notifyAll()方法。

? 一个线程在使用的同步方法中时,可能根据问题的需要,必须使用wait()方法使本线程等待,暂时让出CPU的使用权,并允许其它线程使用这个同步方法。

? 线程如果用完同步方法,应当执行notifyAll()方法通知所有由于使用这个同步方法而处于等待的线程结束等待。

 

2、实验目的与要求

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

(2) 线程综合编程练习

3、实验内容和步骤

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

测试程序1:

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

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

 

package synch;

import java.util.*;
import java.util.concurrent.locks.*;

/**
 * A bank with a number of bank accounts that uses locks for serializing access.
 * @version 1.30 2004-08-01
 * @author Cay Horstmann
 */
public class Bank

   private final double[] accounts;
   private Lock bankLock;
   private Condition sufficientFunds;

   /**
    * Constructs the bank.
    * @param n the number of accounts
    * @param initialBalance the initial balance for each account
    */
   public Bank(int n, double initialBalance)
   
      accounts = new double[n];
      Arrays.fill(accounts, initialBalance);
      bankLock = new ReentrantLock();//锁对象初始化 
      sufficientFunds = bankLock.newCondition();//newCondition方法生成了锁对象的条件对象
   

   /**
    * Transfers money from one account to another.
    * @param from the account to transfer from
    * @param to the account to transfer to
    * @param amount the amount to transfer
    */
   public void transfer(int from, int to, double amount) throws InterruptedException
   //加锁
      bankLock.lock();
      try
      
         while (accounts[from] < amount)
            sufficientFunds.await();//将线程放到条件的等待集中
         System.out.print(Thread.currentThread());
         accounts[from] -= amount;
         System.out.printf(" %10.2f from %d to %d", amount, from, to);
         accounts[to] += amount;
         System.out.printf(" Total Balance: %10.2f%n", getTotalBalance());
         sufficientFunds.signalAll();//解除该条件的等待集中随机的所有线程的阻塞状态
      
      finally
      
         bankLock.unlock();//释放锁
      
   

   /**
    * Gets the sum of all account balances.
    * @return the total balance
    */
   public double getTotalBalance()
   
      bankLock.lock();
      try
      
         double sum = 0;

         for (double a : accounts)
            sum += a;

         return sum;
      
      finally
      
         bankLock.unlock();
      
   

   /**
    * Gets the number of accounts in the bank.
    * @return the number of accounts
    */
   public int size()
   
      return accounts.length;
   

 

package synch;

/**
 * This program shows how multiple threads can safely access a data structure.
 * @version 1.31 2015-06-21
 * @author Cay Horstmann
 */
public class SynchBankTest
//定义四个公共属性
   public static final int NACCOUNTS = 100;
   public static final double INITIAL_BALANCE = 1000;
   public static final double MAX_AMOUNT = 1000;
   public static final int DELAY = 10;
   
   public static void main(String[] args)
   
      Bank bank = new Bank(NACCOUNTS, INITIAL_BALANCE);
      for (int i = 0; i < NACCOUNTS; i++)
      
         int fromAccount = i;
         Runnable r = () -> 
            try//抛出异常
            
               while (true)
               
                  int toAccount = (int) (bank.size() * Math.random());
                  double amount = MAX_AMOUNT * Math.random();
                  bank.transfer(fromAccount, toAccount, amount);
                  Thread.sleep((int) (DELAY * Math.random()));
               
            
            catch (InterruptedException e)
            
                        
         ;
         Thread t = new Thread(r);
         t.start();
      
   

 

技术分享图片

 测试程序2

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

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

 

package synch2;

import java.util.*;

/**
 * A bank with a number of bank accounts that uses synchronization primitives.
 * @version 1.30 2004-08-01
 * @author Cay Horstmann
 */
public class Bank

   private final double[] accounts;

   /**
    * Constructs the bank.
    * @param n the number of accounts
    * @param initialBalance the initial balance for each account
    */
   public Bank(int n, double initialBalance)
   
      accounts = new double[n];
      Arrays.fill(accounts, initialBalance);
   

   /**
    * Transfers money from one account to another.
    * @param from the account to transfer from
    * @param to the account to transfer to
    * @param amount the amount to transfer
    */
   public synchronized void transfer(int from, int to, double amount) throws InterruptedException
   
      while (accounts[from] < amount)
         wait();
      System.out.print(Thread.currentThread());
      accounts[from] -= amount;
      System.out.printf(" %10.2f from %d to %d", amount, from, to);
      accounts[to] += amount;
      System.out.printf(" Total Balance: %10.2f%n", getTotalBalance());
      notifyAll();
   

   /**
    * Gets the sum of all account balances.
    * @return the total balance
    */
   public synchronized double getTotalBalance()
   //计算过程
      double sum = 0;

      for (double a : accounts)
         sum += a;

      return sum;
   

   /**
    * Gets the number of accounts in the bank.
    * @return the number of accounts
    */
   public int size()
   
      return accounts.length;
   

 

package synch2;

/**
 * This program shows how multiple threads can safely access a data structure,
 * using synchronized methods.
 * @version 1.31 2015-06-21
 * @author Cay Horstmann
 */
public class SynchBankTest2

   public static final int NACCOUNTS = 100;
   public static final double INITIAL_BALANCE = 1000;
   public static final double MAX_AMOUNT = 1000;
   public static final int DELAY = 10;

   public static void main(String[] args)
   
      Bank bank = new Bank(NACCOUNTS, INITIAL_BALANCE);
      for (int i = 0; i < NACCOUNTS; i++)
      
         int fromAccount = i;
         Runnable r = () -> 
            try
            
               while (true)
               
                  int toAccount = (int) (bank.size() * Math.random());
                  double amount = MAX_AMOUNT * Math.random();
                  bank.transfer(fromAccount, toAccount, amount);
                  Thread.sleep((int) (DELAY * Math.random()));
               
            
            catch (InterruptedException e)
            
            
         ;
         Thread t = new Thread(r);
         t.start();
      
   

 

技术分享图片

测试程序3

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

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

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();

  

 

class Cbank 
    private static int s = 2000;

    public synchronized 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();
    

 

技术分享图片

实验编程练习

利用多线程及同步方法,编写一个程序模拟火车票售票系统,共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张票

 

package DFDF;

public class DFDF 
    public class Demo 
        public void main(String[] args) 
            Mythread mythread = new Mythread();
            Thread t1 = new Thread(mythread);
            Thread t2 = new Thread(mythread);
            Thread t3 = new Thread(mythread);
            t1.start();
            t2.start();
            t3.start();
        
    

    class Mythread implements Runnable 
        int t = 1;
        boolean flag = true;

        @Override
        public void run() 
            // TODO Auto-generated method stub
            while (flag) 
                try 
                    Thread.sleep(500);
                 catch (Exception e) 
                    // TODO: handle exception
                    e.printStackTrace();
                

                synchronized (this) 
                    if (t <= 10) 
                        System.out.println(Thread.currentThread().getName() + "窗口售:第" + t + "张票");
                        t++;
                    
                    if (t > 10) 
                        flag = false;
                    
                

            

        
    


    

 

技术分享图片

4、实验总结:这次实验中学会了在Java中解决多线程同步问题。

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

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

201771010101白玛次仁《2018面向对象程序设计(java)》第九周学习总结

实验九异常、断言与日志实验时间2018-10-251.知识总结:异常:在程序的执行过程中所发生的异常事件,它中断指令正常执行。程序中出现的常见的错误和问题有:用户输入错误设备错误物理限制代码错误Java把程序运行时可能遇... 查看详情

201771010101白玛次仁《2018面向对象程序设计(java)》第七周学习总结

实验七继承附加实验实验时间2018-10-111.继承的概念:继承在本职上是特殊——一般的关系,即常说的is-a关系。子类继承父类,表明子类是一种特殊的父类,并且具有父类所不具有的一些属性或方法。2.继承中的初始化顺序:从类... 查看详情

201771010101白玛次仁《面向对象程序设计(java)》第十二周实验总结

 实验十二  图形程序设计实验时间 2018-11-14学习总结:1.Java的抽象口工具箱(AbstractWindowToolkit,AWT)包含在java.awt包中,它提供了许多用来设计GUI的组件类和容器类。2.AWT库处理用户界面元素的方法:把图形元素的创... 查看详情

201771010101白玛次仁

本人学号《面向对象程序设计(java)》第一周学习总结第一部分:课程准备部分填写课程学习平台注册账号,平台名称注册账号博客园:www.cnblogs.com 程序设计评测:https://pintia.cn/[email protected]代码托管平台:https://github.c... 查看详情

实验六201771010101白玛次仁

第五章 继承总结实验六继承定义与使用实验时间2018-9-281.类,超类与子类继承Employee类来定义Manager类格式,关键字extends表示继承。Class新类名(子类(subclass),派生类(derivedclass)或孩子类(chideclass))。extends已有类名(超类... 查看详情

201771010101白玛次仁《2018面向对象程序设计(java)》第十七周学习总结(代码片段)

实验十七 线程同步控制实验时间2018-12-101. 知识总结:多线程并发运行不确定性问题解决方案:引入线程同步机制,使得另一线程要使用该方法,就只能等待。 在Java中解决多线程同步问题的方法有两种:-JavaSE5.0中引... 查看详情

201771010101白玛次仁《2018面向对象程序设计(java)》第十六周学习总结(代码片段)

实验十六  线程技术实验时间 2017-12-81.学习总结:1.程序是一段静态的代码,它应用程序执行蓝是一段静态的代码,它应用程序执行蓝本。2.进程是程序的一次动态执行,它对应了从代码加是程序的一次动态执行,,它... 查看详情

20177101010101白玛次仁《面向对象程序设计》第十八周学习总结(代码片段)

实验十八 总复习实验时间2018-12-301、实验目的与要求(1)综合掌握java基本程序结构;(2) 综合掌握java面向对象程序设计特点;(3)综合掌握javaGUI 程序设计结构;(4)综合掌握java多线程编程模型;(5)综合编程练习。2、实验... 查看详情

2018-3-5面向对象(代码片段)

今天学习了有关“面向对象”的内容:传统的面向对象:把将要完成的工作,一个步骤一个步骤的实现,最终完成目标。现代的面向对象:把要做的事情提前存起来,等到需要用的时候调用,相当于设计方法和方法的调用。面向... 查看详情

2018面向对象程序设计(java)第18周学习指导及要求

2018面向对象程序设计(Java)第18周学习指导及要求(2018.12.27-2018.12.30) 学习目标(1)综合掌握java基本程序结构;(2)综合掌握java面向对象程序设计特点;(3)综合掌握javaGUI程序设计结构;(4)综合掌握java多线程编程模型;(5)综合... 查看详情

2018面向对象程序设计(java)第一周

2018面向对象程序设计(Java)第1周学习指导及要求(2018.8.24-2018.9.2) 学习目标了解课程上课方式及老师教学要求,掌握课程学习必要的软件工具;简单了解Java特点及历史;理解JVM、JRE与JDK等概念,学会下载、安装、测试JDK... 查看详情

2018.1.13面向对象之继承复习

classRect{ intwidth=2,height=6; voidsetWidth(intwidth){ this.width=width; //代码1将参数的值赋给成员变量width } voidsetHeight(intheight){ this.height=height; //代码2将参数的值赋给成员变量height } intgetArea(){ returnwidth* 查看详情

2018面向对象程序设计(java)第9周学习指导及要求

2018面向对象程序设计(Java)第9周学习指导及要求(2018.10.25-2018.10.28) 学习目标1.掌握java异常处理技术;2.了解断言的用法;3.了解日志的用途;4.掌握程序基础调试技巧。学习资源1.教材第7章2.第7章教学课件3.corejava.zip4.实... 查看详情

betascrummeeting2

Beta冲刺第二天:2020.6.271.1成员今日分工成员分工白玛次仁录制功能测试视频穷吉软件各项功能测试罗松编写博客焦旭超软件各项功能测试  1.2 今日发现了哪些Bug,描述发现Bug的测试用例和Bug的修复情况;1) json字... 查看详情

betascrummeeting3

Beta冲刺第三天:2020.6.281.1成员今日分工成员分工白玛次仁录制测试视频穷吉软件各项功能测试,修复bug罗松软件各项功能测试,修复bug焦旭超编写博客1.2 今日发现了哪些Bug,描述发现Bug的测试用例和Bug的修复情况;1)微信... 查看详情

2018面向对象程序设计(java)第16周学习指导及要求

2018面向对象程序设计(Java)第17周学习指导及要求(2018.12.20-2018.12.23) 学习目标(1)掌握线程同步的概念及实现技术;(2)Java线程综合编程练习学习资源1.教材第14章2.第14章教学课件3.corejava.zip4.实验十七任务书学习任务增补《... 查看详情

2018年四川理工学院软件工程考试大纲(面向对象的软件开发技术概述)

2018年四川理工学院软件工程考试大纲(面向对象的软件开发技术概述) 1、面向对象软件开发,需要建立哪三种模型 ①、对象模型(用于描述系统的数据结构,定义了系统“对谁做”) ②、动态模型(定义了系统“... 查看详情

2018-2019-220175202实验二《java面向对象程序设计》实验报告

2018-2019-220175202实验二《Java面向对象程序设计》实验报告一、实验内容1.初步掌握单元测试和TDD2.理解并掌握面向对象三要素:封装、继承、多态3.初步掌握UML建模4.熟悉S.O.L.I.D原则5.了解设计模式二、实验要求1.没有Linux基础的同... 查看详情