201871010119-帖佼佼《面向对象程序设计(java)》第十七周学习总结
博文正文开头格式:(2分)
项目 |
内容 |
这个作业属于哪个课程 |
https://www.cnblogs.com/nwnu-daizh/ |
这个作业的要求在哪里 |
https://www.cnblogs.com/nwnu-daizh/p/11435127.html |
作业学习目标 |
(1) 掌握菜单组件用途及常用API; (2) 掌握对话框组件用途及常用API; (3) 学习设计简单应用程序的GUI。 |
随笔博文正文内容包括:
第一部分:总结线程同步技术(10分)
19、线程的同步:
多线程并发运行不确定性问题解决方案:
引入线程同步机制;
在Java中线程同步方法有两种:
(1)JavaSE5.0中引入ReentrantLock类;
20、有关锁对象和条件对象的关键要点:
锁用来保护代码片段,保证任何时刻只能有一个线程被保护执行的代码;
锁管理试图进入被保护的代码段的线程;
锁可拥有一个或多个相关的条件对象;
每个条件对象管理那些已经进入被保护得到代码段但还不能运行的线程;
21、在临界区中使用条件对象的await()、signal()、signalAll()方法实现线程之间的交互:
一个线程在临界区时,可能根据问题的需要,必须使用锁对象的await()方法使本线程等待,暂时让出CPU的使用权,并允许其他线程使用这个同步方法;
线程若退出临界区,应用signal()方法随机的选择一个线程解除其阻塞状态;
线程若退出临界区,执行notifyAll()方法通知所有由于等待该临界区的线程结束等待。
(2)在共享内存中的类方法前加synchronized修饰符;
synchronized关键字作用:
某个类内方法用synchronized修饰符后,该方法被称为同步线程;
只要某个线程正在访问同步方法,其他线程欲要访问同步方法就会被阻塞,直至线程从同步方法返回前唤醒被阻塞线程,其他线程方法可能进入同步方法;
第二部分:实验部分
实验1:测试程序1(5分)
l 在Elipse环境下调试教材651页程序14-7,结合程序运行结果理解程序;
l 掌握利用锁对象和条件对象实现的多线程同步技术。
实验代码如下:
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) //Bank构造器,两个入口参数
{
accounts = new double[n];
Arrays.fill(accounts, initialBalance);
bankLock = new ReentrantLock(); //构建一个可以被用来保护临界区的可重入锁。
sufficientFunds = bankLock.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 = () -> { //Runnable接口实现创建线程
try
{
while (true)
{
int toAccount = (int) (bank.size() * Math.random()); //随机函数产生
double amount = MAX_AMOUNT * Math.random(); //随机函数产生MAX_AMOUNT个随机数
bank.transfer(fromAccount, toAccount, amount); //调用transfer方法在同行之间进行转账
Thread.sleep((int) (DELAY * Math.random())); //随机睡眠时间DELAY
}
}
catch (InterruptedException e)
{
}
};
Thread t = new Thread(r); //创建一个线程
t.start(); //该线程开始工作
}
}
}
运行结果如下:
实验1:测试程序2(5分)
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) //Bank构造器
{
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(); //调用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() //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 = () -> { //Runnable接口创建线程
try
{
while (true)
{
int toAccount = (int) (bank.size() * Math.random()); //随机函数
double amount = MAX_AMOUNT * Math.random(); //产生 1000个随机数
bank.transfer(fromAccount, toAccount, amount); //transfer方法在同行之间进行转账
Thread.sleep((int) (DELAY * Math.random())); //随机产生0-10毫秒之间的一个数,调用sleep方法睡眠。
}
}
catch (InterruptedException e)
{
}
};
Thread t = new Thread(r); //新建一个线程
t.start(); //调用start方法开启线程
}
}
}
运行结果如下:
实验1:测试程序3(5分)
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:结对编程练习包含以下4部分(10分)
利用多线程及同步方法,编写一个程序模拟火车票售票系统,共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) 程序设计思路简述;
在主函数当中创建三个线程,写一个线程类,是实现Runnable接口的类,调用synchronized关键字实现线程的同步。
2) 符合编程规范的程序代码;
3) 程序运行功能界面截图;
实验代码如下:
class thread implements Runnable {
int ticket = 1;
boolean flag = true; @Override
public void run() {
while (flag) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} synchronized (this) {
if (ticket <= 10) {
System.out.println(Thread.currentThread().getName() + "窗口售:第" + ticket + "张票");
ticket++;
}
if (ticket > 10) {
flag = false;
}
}
}
}
} public class Demo {
public static void main(String[] args) {
thread mythread = new thread();
Thread ticket1 = new Thread(mythread);
Thread ticket2 = new Thread(mythread);
Thread ticket3 = new Thread(mythread);
ticket1.start();
ticket2.start();
ticket3.start();
}
}
运行结果如下:
实验总结:(5分)
本周学习了线程的知识,这次作业主要是关于同步线程的知识。上课通过老师的讲解代码以及运行结果的分析,对同步线程又了一定的理解,掌握了线程同步的两种方法。(1)引入ReentrantLock类;(2)在共享内存中的类方法前加synchronized修饰符;
synchronized关键字作用: 某个类内方法用synchronized修饰符后,该方法被称为同步线程; 只要某个线程正在访问同步方法,其他线程欲要访问同步方法就会被阻塞,直至线程从同步方法返回前唤醒被阻塞线程,其他线程方法可能进入同步方法.编程练习是对同步线程的应用。
201871010119-帖佼佼《面向对象程序设计(java)》第十七周学习总结的更多相关文章
- 201771010134杨其菊《面向对象程序设计java》第九周学习总结
第九周学习总结 第一部分:理论知识 异常.断言和调试.日志 1.捕获 ...
- 201871010132-张潇潇《面向对象程序设计(java)》第一周学习总结
面向对象程序设计(Java) 博文正文开头 项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cn ...
- 扎西平措 201571030332《面向对象程序设计 Java 》第一周学习总结
<面向对象程序设计(java)>第一周学习总结 正文开头: 项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 ...
- 杨其菊201771010134《面向对象程序设计Java》第二周学习总结
第三章 Java基本程序设计结构 第一部分:(理论知识部分) 本章主要学习:基本内容:数据类型:变量:运算符:类型转换,字符串,输入输出,控制流程,大数值以及数组. 1.基本概念: 1)标识符:由字母 ...
- 201871010124 王生涛《面向对象程序设计JAVA》第一周学习总结
项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://edu.cnblogs.com/campus/xbsf/ ...
- 201871010115——马北《面向对象程序设计JAVA》第二周学习总结
项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p ...
- 201777010217-金云馨《面向对象程序设计(Java)》第二周学习总结
项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p ...
- 201871010132——张潇潇《面向对象程序设计JAVA》第二周学习总结
项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p ...
- 201771010123汪慧和《面向对象程序设计Java》第二周学习总结
一.理论知识部分 1.标识符由字母.下划线.美元符号和数字组成, 且第一个符号不能为数字.标识符可用作: 类名.变量名.方法名.数组名.文件名等.第二部分:理论知识学习部分 2.关键字就是Java语言 ...
- 马凯军201771010116《面向对象与程序设计Java》第九周学习总结
一.理论知识部分 异常.日志.断言和调试 1.异常:在程序的执行过程中所发生的异常事件,它中断指令的正常执行. 2.Java的异常处理机制可以控制程序从错误产生的位置转移到能够进行错误处理的位置. 3 ...
随机推荐
- Leetcode53_Spiral_Matrix
Spiral_Matrix https://leetcode-cn.com/problems/spiral-matrix/ //当行数只有一行: 1. n = 1; m -> 0; //当列数只 ...
- windows远程工具RDO和RDC使用问题
一. Remote Desktop Organizer远程连接时报错 解决方法: 二. Remote Desktop Connection Manager远程电脑没有全屏,右边和下边有滚动条 解决方法 ...
- luogu1368 工艺
题目链接 思路 \(SAM\)练手题,将原串重复一遍插入到\(SAM\)中,然后贪心走长度为n的一个路径即可. 不用担心会直接走到终点,根据\(SAM\)的构造方式可以发现会先走到前面的路径. 代码 ...
- 【洛谷4045】[JSOI2009] 密码(状压+AC自动机上DP)
点此看题面 大致题意: 给你\(n\)个字符串,问你有多少个长度为\(L\)的字符串,使得这些字符串都是它的子串.若个数不大于\(42\),按字典序输出所有方案. 状压 显然,由于\(n\)很小,我们 ...
- 迷你版mybatis
public class BootStrap { public static void start(){ MySqlSession sqlSession = new MySqlSession();// ...
- sitecore 如何创建一个渠道分类
您可以通过渠道跟踪联系人与您的品牌的所有互动.您可以将渠道与广告系列活动相关联,以便跟踪联系人与您的品牌互动的方式.通过比较各个渠道的目标转化率,您可以了解哪些渠道可以带来更好的联系参与度.您可以在体 ...
- elasticSearch查询(一)
**整理成sql格式来看懂elastic** 1.多个字段多个and查询 sql格式:select * from product where title = 'xxxx' and pid = 12 l ...
- C++回调,函数指针
想要理解回调机制,先要理解函数指针 函数指针 函数指针指向的是函数而非对象,和其他指针一样,函数指针指向某种特定的类型 函数的类型由他的返回类型和参数类型共同决定,与函数名无关,如: bool len ...
- spring boot入门,看这篇文章就够了
一.SpringBoot入门 1.基本介绍 简化Spring应用开发的一个框架.整个Spring技术栈的一个大整合: J2EE开发的一站式解决方案: 优点: 快速创建独立运行的Spring项目以及与主 ...
- Java开发设计——UML类图
Java开发设计——UML类图 摘要:本文主要介绍了UML类图的相关知识. 简介 在UML中,类使用包含类名.属性和操作且带有分隔线的长方形来表示,类图分为三层. 第一层是类的名称,如果是抽象类或接口 ...