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周学习总结的更多相关文章

  1. 201521123045 <java程序设计>第11周学习总结

    201521123045 <java程序设计>第11周学习总结 1. 本周学习总结 2. 书面作业 2. 书面作业 Q1.1.互斥访问与同步访问完成题集4-4(互斥访问)与4-5(同步访问 ...

  2. 201521123027 <java程序设计>第11周学习总结

    1.本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 2.书面作业 1.互斥访问与同步访问 完成题集4-4(互斥访问)与4-5(同步访问) 1.1 除了使用synchro ...

  3. 2018面向对象程序设计(Java)第11周学习指导及要求

    2018面向对象程序设计(Java)第11周学习指导及要求 (2018.11.8-2018.11.11)   学习目标 (1) 掌握Vetor.Stack.Hashtable三个类的用途及常用API: ...

  4. 面向对象程序设计(JAVA) 第11周学习指导及要求

    2019面向对象程序设计(Java)第11周学习指导及要求 (2019.11.8-2018.11.11)   学习目标 理解泛型概念: 掌握泛型类的定义与使用: 掌握泛型方法的声明与使用: 掌握泛型接 ...

  5. 20145236 《Java程序设计》第九周学习总结

    20145236 <Java程序设计>第九周学习总结 教材学习内容总结 第十六章 整合数据库 JDBC简介 1.JDBC是java联机数据库的标准规范.它定义了一组标准类与接口,标准API ...

  6. 2018-2019 2 20175230《Java程序设计》第九周学习总结

    <Java程序设计>第九周学习总结 主要内容 MySQL数据库管理系统 1.下载 2.安装 启动MySQL数据库服务器 1.启动 2.root用户 MySQL客户端管理工具 建立连接 建立 ...

  7. 20175209 《Java程序设计》第九周学习总结

    20175209 <Java程序设计>第九周学习总结 一.教材知识点总结 有关数据库下载中存在可能出现的问题已经在博客<数据库安装和使用过程中出现的一些问题>给出了相应的解决办 ...

  8. 20175208 《Java程序设计》第九周学习总结

    20175208 2018-2019-2 <Java程序设计>第九周学习总结 一.教材学习内容总结: 第11章 JDBC与MySQL数据库 MySQL数据库管理系统 MySQL数据库管理系 ...

  9. 20175202 《Java程序设计》第九周学习总结

    20175202 2018-2019-2 <Java程序设计>第九周学习总结 教材知识点总结 第11章 JDBC与MySQL数据库 MySQL数据库管理系统 MySQL数据库管理系统,简称 ...

  10. 20175227张雪莹 2018-2019-2 《Java程序设计》第九周学习总结

    20175227张雪莹 2018-2019-2 <Java程序设计>第九周学习总结 教材学习内容总结 第十一章 JDBC数据库操作 MySQL数据库管理系统 下载安装MySQL 若下载的是 ...

随机推荐

  1. mysql中kill掉所有锁表的进程

    --mysql中kill掉所有锁表的进程 --------------------------------2014/05/20 在数据库的管理中,我们经常会碰到锁表的问题,看一下进程列表. mysql ...

  2. RMAN备份-未使用catalog-控制文件丢失

    情况描述 客户报告数据库故障,新来的系统管理员误操作.删掉了一些文件.具体情况是:删掉了所有重要数据文件.所有控制文件.数据库原来是归档模式,用rman备份数据,而rman 使用控制文件. 幸运的是, ...

  3. 研究分析JS中的三种逻辑语句

    JS中的三种逻辑语句:顺序.分支和循环语句. 一.顺序语句 代码规范如下:1. <script type="text/javascript"> var a = 10;  ...

  4. Android开发中EditText的点击Enter键焦点改变处理(获取焦点和失去焦点交互变化)

    最近因为项目需要,需要将EditText的焦点转移到LineraLayout上: 即为EditText输入完毕后,点击回车键或者按压其他嵌入式android设备的OK键,获取LineraLayout的 ...

  5. 第一次使用windows版的Git,附上一些配置和最常用的git命令

    Git配置:git config --global user.name "用户姓名" git config --global user.emall "用户邮箱" ...

  6. Django编写RESTful API(一):序列化

    欢迎访问我的个人网站:www.comingnext.cn 关于RESTful API 现在,在开发的过程中,我们经常会听到前后端分离这个技术名词,顾名思义,就是前台的开发和后台的开发分离开.这个技术方 ...

  7. noip普及组2004 FBI树

    FBI树 描述 我们可以把由"0"和"1"组成的字符串分为三类:全"0"串称为B串,全"1"串称为I串,既含" ...

  8. 用Redis实现优先级队列

    在最近在面试过程中,张先森遇到一个面试官这么问,如果一个并发很大的消息应用,想要根据请求的优先级来处理,该怎么做.我当时只是笼统地回答用redis,面试官点了点头,这个问题就此通过. 那么用redis ...

  9. 【Linux 网络】网络测试命令 长期更新

    一.网络测试命令 1.测试 网络连接 发送两包后停发 [oracle@hadoop ~]$ PING www.a.shifen.com (() bytes of data. bytes from tt ...

  10. 转载_2012年的Android之旅:梦想、学习、坚持、自信、淡定

    原文地址:http://blog.csdn.net/luoshengyang/article/details/8452527 2012年的Android之旅:梦想.学习.坚持.自信.淡定.. ---- ...