江西的赣州网站建设,12306网站建设团队,安徽城乡建设部网站首页,制作网页时关于可以采用的图像文件格式正确的描述是课程进入了尾声。本周内容主要是线程安全相关。线程错误比一般的错误更加难以发现和修改#xff0c;甚至加入一条print语句就能改变时间分片#xff0c;从而导致错误消失。重点介绍了“锁”的机制#xff0c;在使用时避免对整个方法进行lock#xff0c;而是对可能发生线程不…课程进入了尾声。本周内容主要是线程安全相关。线程错误比一般的错误更加难以发现和修改甚至加入一条print语句就能改变时间分片从而导致错误消失。重点介绍了“锁”的机制在使用时避免对整个方法进行lock而是对可能发生线程不安全的指令进行lock操作以免程序性能受到明显影响。同时避免“死锁”现象发生在使用多个lock时注意顺序。
并发
1.并行将程序布置在多个CPU上执行。 并发将任务拆分为多个阶段在同一个CPU上执行切片。 2.并发的两个模型共享内存只能用于线程和消息传递线程、进程。
进程和线程
1.进程和线程都是并发模块的类型。进程比较“重量级”私有空间彼此隔离线程“轻量级”是程序内部的控制机制。一个进程可以形成多个线程。 2.每个应用至少有一个线程主线程可以创建其它的线程。 3.创建线程的方法继承Thread从Runnable接口构造Thread对象。
创建线程需要调用Thread类的start方法不能运行具体的run方法
交错Interleaving和竞争
1.时间分片虽然有多个线程但只有一个CPU每个时刻只能执行一个线程。通过时间分片在多个进程/线程间共享处理器。由操作系统自动调度。 2.共享内存时的竞争情况 不恰当的分片操作会导致错误。右侧A和B发生了竞争/线程干扰。 共享内存多线程的运行结果实例每条语句可划分为读取-计算-写回三个原子操作 3.消息传递时的竞争情况 由于时间分片消息传递机制也无法解决竞争问题。 4.调用方法主动影响交错现象 ①Thread.sleep(time) 线程休眠time毫秒 ②Thread.interrupt() 向线程发出中断信号例如t.interrupt()即在其它线程里向t发出中断信号。收到中断信号后t不一定中断由t本身决定。正常运行期间即使收到中断信号也不会理会在休眠时收到中断信号则抛出异常。 ③Thread.join() 让线程保持执行直到其执行结束。执行该操作时也会检测其它线程发来的中断信号。 t1收到中断信号时如果一次循环都未执行则先输入if再输出else如果执行一次则先输出else再输出if如果已经进行两次循环则输出两个else。此外t1和t2的start执行先后不定。
保证线程安全的策略
1.Confinement 要求类中方法不能访问属性过于严格。 2.Immutability 使用不可变数据类型和不可变引用避免多个线程之间的竞争。如果是有益可变性则需要通过“加锁”保证线程安全。 3.使用线程安全数据类型 如果必须使用mutable数据类型在多个线程之间共享数据要使用线程安全的数据类型。一般来说JDK为ADT额外提供一个线程安全的类但性能受影响。List、Map、Set都是线程不安全的API提供集合类的包装对每个操作都以原子操作进行。执行其上的某个操作是线程安全的但如果多个操作放在一起仍然不安全。//即使在线程安全的集合类上使用iterator也是不安全的。除非使用lock机制。
4.锁和同步
①程序员负责多线程之间对mutable数据的共享操作通过同步策略避免多个线程同时访问数据。使用锁机制获得对数据的独家更改权其它线程的访问被阻塞。 ②Lock是Java的内嵌机制每个对象都有相关联的lock。 ③Lock用以保护共享数据。要实现互斥则必须使用同一个lock进行保护。 ④构造方法默认互斥不需加锁。除非必要否则不加锁如果使用要尽量缩小范围。因为会给性能带来极大影响。 ⑤对静态方法进行加锁会同时锁住类的所有对象。 ⑥1和4正确。A获得了list的锁并不意味着其它对象不能获取/改变list的元素。对同一个mutable对象的操作必须在各线程里用synchronized全部保护起来。对于该例子即是将B的两条语句锁住。 ⑦3和4需要锁住。 ⑧使用lock的条件任何共享的mutable变量/对象在被读/写的时候必须加锁。涉及到多个mutable变量的时候它们必须被同一个lock保护例如开始和结束时间。
死锁
1.多个线程竞争lock相互等待对方释放lock必须满足多个线程使用多个锁、访问顺序不同。 2.避免方法多个线程使用同一顺序的lock用单个lock保护多个对象粗粒度。
wait(), notify(), notifyAll()
都是object类的方法。需要在synchronized块中调用要求调用对象和lock的对象相同。 o.wait(): 释放o的锁阻塞当前线程进入到o的等待队列中。 o.notify(): 唤醒等待队列的一个线程。 o.notifyAll(): 唤醒等待队列的所有线程。