关键词:
一.理论知识部分
Java 的线程调度采用优先级策略:优先级高的先执行,优先级低的后执行;多线程系统会自动为每个线程分配一个优先级,缺省时,继承其父类的优先级; 任务紧急的线程,其优先级较高; 同优先级的线程按“先进先出”的队列原则。
调用setPriority(int a)重置当前线程的优先级,a取值可以是前述的三个静态量。调用getPriority()获得当前线程优先级。
多线程并发运行不确定性问题解决方案:引入线程同步机制,使得另一线程要使用该方法,就只能等待。
在Java中解决多线程同步问题的方法有两种:J ava SE 5.0中引入ReentrantLock类。 在共享内存的类方法前加synchronized修饰符。
有关锁对象和条件对象的关键要点:锁用来保护代码片段,保证任何时刻只能有一个线程执行被保护的代码。锁管理试图进入被保护代码段的线程。锁可拥有一个或多个相关条件对象。每个条件对象管理那些已经进入被保护的代码 段但还不能运行的线程。
synchronized关键字作用: 某个类内方法用synchronized 修饰后,该方法被称为同步方法;只要某个线程正在访问同步方法,其他线程欲要访问同步方法就被阻塞,直至线程从同 步方法返回前唤醒被阻塞线程,其他线程方可能进入同步方法。
在同步方法中使用wait()、notify 和notifyAll()方法:一个线程在使用的同步方法中时,可能根据问题的需要,必须使用wait()方法使本线程等待,暂时让出CPU的使用权,并允许其它线程使用这个同步方法。线程如果用完同步方法,应当执行notifyAll()方 法通知所有由于使用这个同步方法而处于等待的线程结束等待。
实验十七 线程同步控制
实验时间 2018-12-10
1、实验目的与要求
(1) 掌握线程同步的概念及实现技术;
(2) 线程综合编程练习
2、实验内容和步骤
实验1:测试程序并进行代码注释。
测试程序1:
l 在Elipse环境下调试教材651页程序14-7,结合程序运行结果理解程序;
l 掌握利用锁对象和条件对象实现的多线程同步技术。
package synch; 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 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 (Interrupt
测试程序2:
l 在Elipse环境下调试教材655页程序14-8,结合程序运行结果理解程序;
l 掌握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:
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();
|
实验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张票
package synch; public class SynchBankTest /** * java多线程同步锁的使用 * 示例:三个售票窗口同时出售10张票 * */ public static void main(String[] args) //实例化站台对象,并为每一个站台取名字 Station station1=new Station("窗口1"); Station station2=new Station("窗口2"); Station station3=new Station("窗口3"); // 让每一个站台对象各自开始工作 station1.start(); station2.start(); station3.start();
package synch; public class Station extends Thread // 通过构造方法给线程名字赋值 public Station(String name) super(name);// 给线程名字赋值 // 为了保持票数的一致,票数要静态 static int tick = 10; // 创建一个静态钥匙 static Object ob = "aa";//值是任意的 // 重写run方法,实现买票操作 @Override public void run() while (tick > 0) synchronized (ob) // 这个很重要,必须使用一个锁, // 进去的人会把钥匙拿在手上,出来后才把钥匙拿让出来 if (tick > 0) System.out.println(getName() + "售出了第" + tick + "张票"); tick--; else System.out.println("票卖完了"); try sleep(1000);//休息一秒 catch (InterruptedException e) e.printStackTrace();
实验总结:
通过这次实验学习到了很多东西,主要掌握了多线程在程序中的的实现。本周实验还是挺轻松的,自己顺利的完成了。
马凯军201771010116《面向对象程序设计(java)》第一周学习总结
马凯军201771010116《面向对象程序设计(java)》第一周学习总结第一部分:课程准备部分填写课程学习平台注册账号,平台名称注册账号博客园:www.cnblogs.com消遣流年。程序设计评测:https://pintia.cn/[email protected]代码托管平台... 查看详情
马凯军201771010116《面向对象与程序设计java》第十五周学习知识总结(代码片段)
&n 查看详情
马凯军201771010116《面向对象与程序设计java》第十二周学习总结(代码片段)
一、理论与知识学习部分Java的抽象窗口工具箱(AbstractWindowToolkit,AWT)包含在java.awt包中,它提供了许多用来设计GUI的组件类和容器类。大部分AWT组件都有其Swing的等价组件,Swing组件的名字一般是在AWT组件名前面添加一个字母“J... 查看详情
马凯军201771010116《面向对象与程序设计java》第九周学习总结(代码片段)
一.理论知识部分 异常、日志、断言和调试1.异常:在程序的执行过程中所发生的异常事件,它中断指令的正常执行。2.Java的异常处理机制可以控制程序从错误产生的位置转移到能够进行错误处理的位置。3.程序中出现的常见的... 查看详情
马凯军201771010116《面向对象与程序设计java》第十一周学习总结(代码片段)
一.理论知识部分第九章 集合1.数据结构介绍:线性结构:线性表,栈,队列,串,数组,文件。非线性结构:树,图。散列表:又称为哈希表。散列表算法的基本思想是:以结点的关键字为自变量,通过一定的函数关系(散... 查看详情
马凯军201771010116《面向对象程序设计(java)》第七周学习总结(代码片段)
理论与知识部分多态性:概念:指在程序中同一符号在不同的情况下具有不同的解释。超类中定义的域或方法,被子类继承之后,可以具有不同的数据类型或表现出不同的行为。这使得同一域或方法在超类及各个子类中具有... 查看详情
马凯军201771010116《面向对象程序设计(java)》第三周学习总结(代码片段)
第一部分 理论知识学习与复习部分1、在第一章里主要对Java中常见的误解这部分进行了细读,也对Java的“白皮书”术语认真的看了一遍,对Java术语有了更深的理解。2、在第二章中对Java程序的编辑环境eclipse通过课本理... 查看详情
马凯军201771010116《面向对象程序设计(java)》第六周学习总结(代码片段)
第一部分:理论知识学习部分 枚举是一种特殊的数据类型,之所以特殊是因为它既是一种类(class)类型却又比类型多了些特殊的约束,但是这些约束的存在也造就了枚举类型的简洁,安全性以及便捷性。创建... 查看详情
马凯军201771010116《面向对象与程序设计java》第十七周学习总结(代码片段)
一.理论知识部分 Java的线程调度采用优先级策略:优先级高的先执行,优先级低的后执行;多线程系统会自动为每个线程分配一个优先级,缺省时,继承其父类的优先级;任务紧急的线程,其优先级较高;同优先级的线程按“... 查看详情
马凯军201771010116《面向对象与程序设计java》第十六周知识学习总结(代码片段)
一:理论知识部分1.线程的概念:程序是一段静态的代码,它是应用程序执行的蓝本。‐进程是程序的一次动态执行,它对应了从代码加载、执行至执行完毕的一个完整过程。多线程是进程执行过程中产生的多条执行线索。‐线... 查看详情
设计模式与面向对象
面向对象基础抽象封装继承多态组合良好的OO设计可复用可扩充可维护设计模式 查看详情
面向对象的程序设计
阅读目录一面向对象的程序设计的由来二什么是面向对象的程序设计及为什么要有它三类与对象四属性查找五绑定到对象的方法的特殊之处六对象之间的交互七练习八继承与派生九多态与多态性十封装十一绑定方法与非绑定方法... 查看详情
面向对象
一面向对象的程序设计的由来二什么是面向对象的程序设计及为什么要有它三类与对象四属性查找五绑定到对象的方法的特殊之处六对象之间的交互七练习八继承与派生九多态与多态性十封装十一绑定方法与非绑定方法十二小白... 查看详情
面向对象的编程思想和java中类的概念与设计
面向对象的编程思想学习,面向对象内容的三条主线;1.java类及类的对象2.面向对象的三大特征3.其他关键字学习内容:3.1面向对象与面向过程面向对象与面向过程在应用上的区别Java中类的概念与设计类与类之间的关系面向对象的... 查看详情
面向对象与面向过程区别
...步一步实现,使用时依次调用就可以了;区别:面向对象程序设计,往往是从问题的一部分着手,一点一点地构建出整个程序。面向对象设计以数据为中心,类作为表现数据的工具,成为划分程序的基本单位;面向对象是一个抽... 查看详情
面向对象(代码片段)
阅读目录一面向对象的程序设计的由来二什么是面向对象的程序设计及为什么要有它三类与对象四属性查找五绑定到对象的方法的特殊之处六对象之间的交互七练习八继承与派生九多态与多态性十封装十一绑定方法与非绑定方法... 查看详情
面向对象的程序设计
一面向对象的程序设计的由来二什么是面向对象的程序设计及为什么要有它三类和对象3.1类相关知识3.2对象相关知识3.3对象之间的交互3.4类名称空间与对象/实例名称空间3.5小结四继承与派生4.1什么是继承4.2继承与抽象(先抽象... 查看详情
java与面向对象设计
1面向对象与面向过程2.OO的特点 (1)封装性(2)继承性(3)多态性3.ClassandObject(1)defineaclass(2)gloablesandlocalvariables(3)constructor‘sdefinationandapplication(4)createanobjectdeclrationanobject allocatememory(5)us 查看详情