201521123011《Java程序设计》第11周学习总结
1. 本周学习总结
1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容。
2. 书面作业
本次PTA作业题集多线程
1.互斥访问与同步访问
完成题集4-4(互斥访问)与4-5(同步访问)
1.1 除了使用synchronized修饰方法实现互斥同步访问,还有什么办法实现互斥同步访问(请出现相关代码)?
1.2 同步代码块与同步方法有何区别?
1.3 实现互斥访问的原理是什么?请使用对象锁概念并结合相应的代码块进行说明。当程序执行synchronized同步代码块或者同步方法时,线程的状态是怎么变化的?
1.4 Java多线程中使用什么关键字实现线程之间的通信,进而实现线程的协同工作?为什么同步访问一般都要放到synchronized方法或者代码块中?
答:1.1
在Java中,提供了两种方式来实现同步互斥访问:synchronized和Lock
class Account{
private int balance;
private Lock poolLock = new ReentrantLock();
private Condition condition = poolLock.newCondition();
public Account(int balance) {
super();
this.balance = balance;
}
public int getBalance() {
return balance;
}
public void deposit(int money){
poolLock.lock();
try{
this.balance=getBalance() + money;
condition.signal();
}
finally
{
poolLock.unlock();
}
}
public void withdraw(int money){
poolLock.lock();
try{
while (getBalance() <money) {
try {
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.balance=getBalance() - money;
condition.signal();
}
finally{
poolLock.unlock();
}
}
}
1.2
同步代码和同步方法是一样的,同步方法作用于整个方法,同步代码块作用于整个代码块而已。
1、当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。
2、然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。
3、尤其关键的是,当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞。
1.3
同一时刻,只能有一个线程获得某个资源的锁,访问该资源,其他线程无法访问它直至该资源被解锁。
class Counter {
private static int id = 0;
public static void addId() {
synchronized (Counter.class) {
id++;
}
}
public static synchronized void subtractId() {
id--;
}
public static int getId() {
return id;
}
}
1.线程a获得id的锁,读取id的值id=0
2.线程a执行id++,结果id=1
3.线程a将结果存回id,id=1,id的锁被解锁资源释放
4.线程b获得id上的锁,读取id的值id=1
5.线程b执行id--即1-1=0,此时id=0
6.线程b将结果存回id,id现在为0,id的锁被解锁资源释放
1.4
用wait()、notify()来实现线程之间的协作,放到synchronized方法或者代码块是为了防止多个线程访问同一资源所引起的冲突。
2.交替执行
实验总结(不管有没有做出来)
答:
2.1
这题除了方法要用synchronized来修饰之外。还使用wait()和notify()来进行线程之间的协作。当任务1执行完后,改变flag为true,开始换任务2执行,任务2执行完后,改变flag为false,再换任务1执行,就这样实现交替执行。
public synchronized void run1(){
while(getSize()>0){
if(flag){
try{
wait();
}catch (InterruptedException e) {
e.printStackTrace();
// TODO: handle exception
}
}
System.out.println(Thread.currentThread().getName()+" finish "+str[i]);
i++;
flag=true;
notify();
}
}
public synchronized void run2(){
while(getSize()>0){
if(!flag){
try{
wait();
}catch (InterruptedException e) {
e.printStackTrace();
// TODO: handle exception
}
}
System.out.println(Thread.currentThread().getName()+" finish "+str[i]);
i++;
flag=flase;
notify();
}
}
3.互斥访问
3.1 修改TestUnSynchronizedThread.java源代码使其可以同步访问。(关键代码截图,需出现学号)
3.2 进一步使用执行器改进相应代码(关键代码截图,需出现学号)
参考资料:Java多线程之Executor、ExecutorService、Executors、Callable、Future与FutureTask
答:
3.1
//201521123011
class Counter {
private static int id = 0;
public static synchronized void addId() {
id++;
}
public static synchronized void subtractId() {
id--;
}
public static int getId() {
return id;
}
}
3.2
//201521123011
int n=3;
List<Callable<Object>> listtask=new ArrayList<>();
ExecutorService exec=Executors.newCachedThreadPool();
for (int i = 0; i < n; i++) {
task.add(Executors.callable(new Adder()));
}
for (int i = 0; i < n; i++) {
task.add(Executors.callable(new Subtracter()));
}
exec.invokeAll(task);
System.out.println(Counter.getId());
System.out.println("main end");
4.线程间的合作:生产者消费者问题
4.1 运行MyProducerConsumerTest.java。正常运行结果应该是仓库还剩0个货物。多运行几次,观察结果,并回答:结果正常吗?哪里不正常?为什么?
4.2 使用synchronized, wait, notify解决该问题(关键代码截图,需出现学号)
4.3 选做:使用Lock与Condition对象解决该问题。
答:
4.1
不正常,会出现10个货物的情况
问题主要出在public synchronized void add(String t)
和public synchronized void remove()
的方法上,需要加上wait()和notify()函数来实现线程之间的合作
4.2
//201521123011
public synchronized void add(String t) {
while(repo.size()>=capacity){
try{
wait();
System.out.println("仓库已满!无法添加货物。");
}catch (InterruptedException e) {
e.printStackTrace();
// TODO: handle exception
}
}
repo.add(t);
notify();
}
public synchronized void remove() {
while(repo.size()<=0){
try{
wait();
System.out.println("仓库无货!无法从仓库取货");
}catch (InterruptedException e) {
e.printStackTrace();
// TODO: handle exception
}
}
repo.remove(0);
notify();
}
4.3
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
public synchronized void add(String t) {
lock.lock();
try{
while(repo.size()>=capacity){
try{
condition.await();
System.out.println("仓库已满!无法添加货物。");
}catch (InterruptedException e) {
e.printStackTrace();
// TODO: handle exception
}
}
repo.add(t);
condition.signal();
}finally {
lock.unlock();
}
}
public synchronized void remove() {
try{
while(repo.size()<=0){
try{
condition.await();
System.out.println("仓库无货!无法从仓库取货");
}catch (InterruptedException e) {
e.printStackTrace();
// TODO: handle exception
}
}
repo.remove(0);
condition.signal();
}finally {
lock.unlock();
}
}
5.查询资料回答:什么是线程安全?(用自己的话与代码总结,写自己看的懂的作业)
答:
线程安全就是说多线程访问同一代码,不会产生不确定的结果。
线程安全一般都涉及到synchronized 就是一段代码同时只能有一个线程来操作。
如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。
3. 码云上代码提交记录
题目集:多线程(4-4到4-10)
3.1. 码云代码提交记录
3.2 截图多线程PTA提交列表
201521123011《Java程序设计》第11周学习总结的更多相关文章
- 201521123045 <java程序设计>第11周学习总结
201521123045 <java程序设计>第11周学习总结 1. 本周学习总结 2. 书面作业 2. 书面作业 Q1.1.互斥访问与同步访问完成题集4-4(互斥访问)与4-5(同步访问 ...
- 201521123027 <java程序设计>第11周学习总结
1.本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 2.书面作业 1.互斥访问与同步访问 完成题集4-4(互斥访问)与4-5(同步访问) 1.1 除了使用synchro ...
- 2018面向对象程序设计(Java)第11周学习指导及要求
2018面向对象程序设计(Java)第11周学习指导及要求 (2018.11.8-2018.11.11) 学习目标 (1) 掌握Vetor.Stack.Hashtable三个类的用途及常用API: ...
- 面向对象程序设计(JAVA) 第11周学习指导及要求
2019面向对象程序设计(Java)第11周学习指导及要求 (2019.11.8-2018.11.11) 学习目标 理解泛型概念: 掌握泛型类的定义与使用: 掌握泛型方法的声明与使用: 掌握泛型接 ...
- 20145236 《Java程序设计》第九周学习总结
20145236 <Java程序设计>第九周学习总结 教材学习内容总结 第十六章 整合数据库 JDBC简介 1.JDBC是java联机数据库的标准规范.它定义了一组标准类与接口,标准API ...
- 2018-2019 2 20175230《Java程序设计》第九周学习总结
<Java程序设计>第九周学习总结 主要内容 MySQL数据库管理系统 1.下载 2.安装 启动MySQL数据库服务器 1.启动 2.root用户 MySQL客户端管理工具 建立连接 建立 ...
- 20175209 《Java程序设计》第九周学习总结
20175209 <Java程序设计>第九周学习总结 一.教材知识点总结 有关数据库下载中存在可能出现的问题已经在博客<数据库安装和使用过程中出现的一些问题>给出了相应的解决办 ...
- 20175208 《Java程序设计》第九周学习总结
20175208 2018-2019-2 <Java程序设计>第九周学习总结 一.教材学习内容总结: 第11章 JDBC与MySQL数据库 MySQL数据库管理系统 MySQL数据库管理系 ...
- 20175202 《Java程序设计》第九周学习总结
20175202 2018-2019-2 <Java程序设计>第九周学习总结 教材知识点总结 第11章 JDBC与MySQL数据库 MySQL数据库管理系统 MySQL数据库管理系统,简称 ...
- 20175227张雪莹 2018-2019-2 《Java程序设计》第九周学习总结
20175227张雪莹 2018-2019-2 <Java程序设计>第九周学习总结 教材学习内容总结 第十一章 JDBC数据库操作 MySQL数据库管理系统 下载安装MySQL 若下载的是 ...
随机推荐
- ThinkSNS+ alpha.2 版本发布,功能抢先看!【社交系统研发日记六】
今天的研发日记,我们不讲技术,我们来看看,社交系统TS+从今天开始全面内测开始,都发布了什么功能. 其实,alpha.1 早上打的 tag ,晚上因为增加了两个核心功能,所以又打了 alpha.2 t ...
- selenium 相关api操作
driver.close(); //关闭程序 driver.findElement(By.id("idExpression")); //查找单个页面元素 driver.findEl ...
- css基础知识之属性选择器
css属性选择器及属性和值选择器如下: <!DOCTYPE html> <html lang="en"> <head> <meta cha ...
- fiddler mock ==> AutoResponder
背景 做过测试的同学,肯定都听过fiddler的大名,抓包工具,app抓包 下载传送门(https://www.telerik.com/download/fiddler) 抓包使用这里就不复述了,这次 ...
- scope引起的问题
背景 执行mvn clean test命令提示部分包不存在,但通过eclipse的clean操作后可以执行mvn test命令 解决方法 mvn clean操作为清空编译的class文件,test的话 ...
- Nuget安装nupkg文件
问题描述: VS出现故障不能使用Manage NuGet Package自动下载安装DLL 解决方案: 直接官网下载相关需要的DLL 在VS中使用console加载本地下载的包安装 控制台code参考 ...
- C#使用Xamarin开发可移植移动应用进阶篇(9.混淆代码,防止反编译)
前言 系列目录 C#使用Xamarin开发可移植移动应用目录 源码地址:https://github.com/l2999019/DemoApp 可以Star一下,随意 - - 说点什么.. 今天讲讲如 ...
- 关于request、response转发与重定向的简述
在做页面的请求与响应的时候我们多用request与response进行操作,而我们大家也知道,request是表示用户发向服务器的请求,而response是对用户请求的一个响应. 关于转发和重定向,通 ...
- 在JS事件封装时,addEventListener()方法的this问题
最近在写js的类库,模仿的是jquery的编程风格,当封装到事件监听的时候发现遇到了一个问题,代码是这样的: 上面是封装的一个事件委托的代码,我以为上面的封装跟普通的事件监听一样简单,结果我在调用时发 ...
- MyBatis --- 动态SQL、缓存机制
有的时候需要根据要查询的参数动态的拼接SQL语句 常用标签: - if:字符判断 - choose[when...otherwise]:分支选择 - trim[where,set]:字符串截取,其中w ...