201521123004 《Java程序设计》第11周学习总结
1. 本周学习总结
1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容。
- 注意: notify()/notifyAll()方法和wait()方法都只能在被声明为synchronized的方法或代码段中调用。
2. 书面作业:本次PTA作业题集多线程
互斥访问与同步访问:完成题集4-4(互斥访问)与4-5(同步访问)
1.1 除了使用synchronized修饰方法实现互斥同步访问,还有什么办法实现互斥同步访问(请出现相关代码)?
答:
还有lock(ReentrantLock(可重入锁),lock,unlock方法)和使用条件对象(条件变量—信号量,Condition)
private Lock lock = new ReentrantLock();``private Condition condition = lock.newCondition();
通过以上两句定义一个lock对象和一个condition对象来实现互斥同步访问。
- 使用条件对象(条件变量—信号量,Condition)
- Condition对象需要搭配Lock对象来使用
- Lock lock = new ReentrantLock();
- Condition condition = lock.newCondition();
- 实现同步的方法
- condition.await() //类似object的wait
- condition.signal() //类似object的notify
- condition.signalAll() //类似object的notifyAll()
关键代码如下截图:
1.2 同步代码块与同步方法有何区别?
答:
①在代表原子操作的程序代码前加上synchronized标记,这样的代码被称为synchronized方法。简单说就是有synchronized关键字修饰的方法
需要注意的是synchronized关键字也可以修饰静态方法,此时如果调用该静态方法,将会锁住整个类
例如:
public static synchronized void addId() {
id++;
}
②synchronized代码块即有synchronized关键字修饰的语句块。
例如:
public static void addId() {
synchronized(Counter.class){//代表Counter类型的对象
id++;
}
}
③除了定义和格式不一样之外,同步代码块与同步方法的区别还在于同步代码块锁住的是语句而同步方法锁住的是整个方法。
1.3 实现互斥访问的原理是什么?请使用对象锁概念并结合相应的代码块进行说明。当程序执行synchronized同步代码块或者同步方法时,线程的状态是怎么变化的?
答:
①需要实现互斥访问的原因是有时两个或两个以上的线程需要同时对同一资源存取,而线程之间如果不加以控制,会产生一种情况-竞争;线程对该资源进行操作时即上锁,这样其他同步线程就无法获取资源,等执行中的线程结束之后,释放资源,让其他线程继续争取对资源的使用权。
②关于对象锁:每个对象都有一把锁,如果未获得对象锁,下面的代码就无法执行,必须等待。从而通过对象锁实现了互斥访问。
class MyCounter{
private int i = 0;
public void increment(){
synchronized (this) {//获得this这个对象上的内部锁
i++;
}
}
}
③假设线程A与线程B同时争取同一个资源,当A和B同时获取CPU进入Running之后,只能有一个线程(假设为A)获得资源的使用权,那么A线程就能进入LockPool获取同步锁继续执行,结束后将同步锁释放出来,而B就要进入WaitPool(通过wait();
)等待同步锁被释放后进入LockPool(通过notify();/notifyAll();
)重新争取同步锁。
1.4 Java多线程中使用什么关键字实现线程之间的通信,进而实现线程的协同工作?为什么同步访问一般都要放到synchronized方法或者代码块中?
答:
①Java多线程中使用synchronized
关键字以及wait();``notify();``notifyAll();
实现线程之间的通信,进而实现线程的协同工作。
②同步访问一般都要放到synchronized方法或者代码块中就是将方法或代码块上锁的过程,这样多个线程有冲突时,才能通过‘执行获得同步锁的线程’这样的原则来解决多个线程之间的竞争问题,才不会导致代码运行结果出错。
交替执行
实验总结(不管有没有做出来)
答:首先通过task = items.split(" ");
将传递进来的字符串以空格区分分解为多个不同的任务;task.length - i;
Repo包含的任务数量(完成任务的时候,需要将任务删除->i);设一个布尔型的flag来判断任务1和2是否执行,当flag!=true
时,任务1wait();
(eclipse会提示你要放在try-catch里面的),否则如果Repo里还有任务时就执行下一个并输出结果,此时,完成的任务个数i就会改变task[i++]
,任务2类似;接下来定义Worker1与Worker2类,从Repo对象中获取任务run1与run2;
看来我对pta的中文识别能力一无所知,一直编译错误,后来才想起来pta不喜欢中文,赶紧把代码的中文提示删掉,果然。
互斥访问
3.1 修改TestUnSynchronizedThread.java源代码使其可以同步访问。(关键代码截图,需出现学号)
答:修改后的关键代码及结果截图如下:
3.2 进一步使用执行器改进相应代码(关键代码截图,需出现学号)
参考资料:Java多线程之Executor、ExecutorService、Executors、Callable、Future与FutureTask
答:对Executor还不是太了解,虽然改进后的代码能运行,但是结果却不是0,不知道是哪里错了
线程间的合作:生产者消费者问题
4.1 运行MyProducerConsumerTest.java。正常运行结果应该是仓库还剩0个货物。多运行几次,观察结果,并回答:结果正常吗?哪里不正常?为什么?
答:结果不正常,运行十次发现不知出现“仓库还剩0个货物”还出现“仓库还剩10个货物”。
不正常:
public synchronized void add(String t) {
if (repo.size() >= capacity) {
System.out.println("仓库已满!无法添加货物。");//那货物怎么办呢?
} else {
repo.add(t);
}
}
原因在于当生产者向仓库添加货物而此时仓库已满,代码中仅仅输出仓满,而没有对这些货物作出处理(比如扔掉或者等消费者取走等量货物后再放入)。
4.2 使用synchronized, wait, notify解决该问题(关键代码截图,需出现学号)
答:截图如下
4.3 选做:使用Lock与Condition对象解决该问题
答:结合书面作业1.1,截图如下
查询资料回答
什么是线程安全?(用自己的话与代码总结,写自己看的懂的作业)
答:
线程安全:如果代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,那么就是线程安全的。更专业一点的说法是:一个类或者程序所提供的接口对于线程来说是原子操作或者多个线程之间的切换不会导致该接口的执行结果存在二义性,也就是说我们不用考虑同步的问题。
举个反例:
比如i++
执行的时候可能会有两步来完成:1.x=i+1;2.i=x。在单线程运行的情况下,如果 i= 0,i++
后,i=1;而如果是在多线程情况下,比如有两个线程,线程 A 取i得值为0,但是此时 CPU 调度线程A暂停,线程 B 得到运行的机会。线程B也取得i=0的值,因为此时i还是原来的值,并未被线程A改变,所以线程B也是i=0。然后线程A和线程B都继续运行,都执行i++
,结果i都等于1。这就很明显,i通过线程AB进行两次自加,结果应该为2的,但是却等于1,这就是"线程不安全"了。
选做:实验总结
6.1 4-8(CountDownLatch)实验总结
答:看到题目发现不认识,吓得我赶紧查了一下,‘CountDownLatch类是一个同步计数器,构造时传入int参数,该参数就是计数器的初始值,每调用一次countDown()方法,计数器减1,计数器大于0 时,await()方法会阻塞程序继续执行;CountDownLatch如其所写,是一个倒计数的锁存器,当计数减至0时触发特定的事件。利用这种特性,可以让主线程等待子线程的结束。’,创建计数器和执行器不难,跟书面作业3.2截图里的做法差不多,只是换了Executors.newFixedThreadPool();
然后for循环exec.execute(new MyTask(latch));
.
6.2 4-9(集合同步问题)实验总结
答:Collections.synchronizedList(new ArrayList());
参考链接
6.3 较难:4-10(Callable),并回答为什么有Runnable了还需要Callable?实验总结。
选做:使用其他方法解决题目4的生产者消费者问题。
7.1 使用BlockingQueue解决生产者消费者问题关键代码截图
7.2 说明为什么不需要显示的使用wait、notify就可以解决同步问题。这样解决相比较wait、notify有什么优点吗?
答:如果BlockQueue是空的,从BlockingQueue取东西的操作将会被阻断进入等待状态,直到BlockingQueue进了东西才会被唤醒.同样,如果BlockingQueue是满的,任何试图往里存东西的操作也会被阻断进入等待状态,直到BlockingQueue里有空间才会被唤醒继续操作.
[参考博客:线程----BlockingQueue](http://www.cnblogs.com/likwo/archive/2010/07/01/1769199.html)
7.3 使用Condition解决生产者、消费者问题。
答:结合书面作业1.1(Lock和Condition),截图如下
选做:编写一段代码,证明你会使用ForkJoinPool?
3. 码云上代码提交记录
题目集:多线程(4-4到4-10)
3.1. 码云代码提交记录:在码云的项目中,依次选择“统计-Commits历史-设置时间段”, 然后搜索并截图
3.2 截图多线程PTA提交列表
4.选做
课外阅读
4.1Questions and Exercises: Concurrency,学习总结。
4.2Java多线程之Executor、ExecutorService、Executors、Callable、Future与FutureTask
4.3线程池,这一篇或许就够了
4.4 Java 8 Concurrency Tutorial: Threads and Executors
201521123004 《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 若下载的是 ...
随机推荐
- 关于 Overtrue 的拼音库 overtrue/pinyin 为何 travis 为 error【社交系统研发日记十】
什么是ThinkSNS ? ThinkSNS(简称TS),一款全平台综合性社交系统,为国内外大中小企业和创业者提供社会化软件研发及技术解决方案,目前最新版本为ThinkSNS+(简称TS+).社交系统 ...
- Apriori关联分析算法概述
概念 关联分析:从大规模数据集中寻找物品间的隐含关系.物品间关系又分为两种:频繁项集或关联规则,频繁项集是经常出现一块的物品集合:关联规则则暗示物品间存在很强的联系 关联评判标准:支持度和可信度.支持 ...
- Qt窗体引用window自带阴影边框效果
<1>.工程pro文件添加Dwmapi.lib LIBS += Dwmapi.lib <2>.窗体控件添加系统函数 #ifdef Q_OS_WIN #include <D ...
- 学习笔记TF051:生成式对抗网络
生成式对抗网络(gennerative adversarial network,GAN),谷歌2014年提出网络模型.灵感自二人博弈的零和博弈,目前最火的非监督深度学习.GAN之父,Ian J.Goo ...
- 设计模式原则(2)--Liskov Substitution Principle(LSP)--里氏替换原则
1.定义: 所有引用基类(父类)的地方必须能透明地使用其子类的对象.这一原则与继承紧密相关.如果对每一个类型为 T1的对象 o1,都有类型为 T2 的对象o2,使得以 T1定义的所有程序 P 在所有的 ...
- ffmpeg音频播放代码示例-avcodec_decode_audio4
一.概述 最近在学习ffmpeg解码的内容,参考了官方的教程http://dranger.com/ffmpeg/tutorial03.html,结果发现这个音频解码的教程有点问题.参考了各种博客,并同 ...
- JVM堆内存设置
今天碰到了一个题目,讲的是关于堆内存的问题,题目如下 下面哪种情况会导致持久区jvm堆内存溢出? A.循环上万次的字符串处理 B.在一段代码内申请上百M甚至上G的内存 C.使用CGLib技术直接操 ...
- 分享一个数据库工具DTOOLS
整理电脑的时候发现一个好的工具——DTOOLS,他是我在09年左右写的一个数据库工具. 可以干什么呢? 我罗列一下: 1.全面的展示数据库字段情况 2. 迅速切换,展示数据库记录情况,不输语句,即点即 ...
- Win7里面如何把这一堆图标放进那个右下角的小三角框框
Win7里面如何把这一堆图标放进那个右下角的小三角框框.. Win7里面如何把这一堆图标放进那个小框框:1.在任务栏空白处右击,点击属性:2.在属性中的通知区域-->点击自定义按钮:3.去除勾选 ...
- Windows7 中常用的一些DOS命令总结
Windows7 中常用的一些DOS命令总结... ----------------------- -------------------------------------------- dos,是 ...