现在的位置: 首页 > 综合 > 正文

Java编程思想学习笔记——并发

2014年03月11日 ⁄ 综合 ⁄ 共 4251字 ⁄ 字号 评论关闭

1. java.util.concurrency包中的ExcecutorService类执行线程任务时,用它的exec()方法提交任务。实现Runnable接口的类不含返回值,若想要返回值,需要实现Callable接口,用submit方法提交任务。它会返回一个Future对象,从中可获得返回值及判断线程状态等。

2. yield()方法表示当前线程已经完成或暂时不需要CPU,其它线程可以占用之,这只是个建议。

3. 可以为线程设置优先级,具体调度交由操作系统,所以优先级只能是种参考,Java只提供了MAX、MIN、NORM三种优先级供参考。具体执行结果因平台而异。

4. 后台(daemon)线程是指程序运行时在后台提供一种能用服务的线程,并且该线程不属于程序不可或缺的一部分。所有非后台线程杀死后,后台线程也就随之结束了。线程对象有setDaemon(boolean)方法。

5. 一个线程可以在其它线程上调用join()方法,意为等该线程执行完成之后再继续当前线程。

6. 由于线程的特性,使得无法捕获从线程中逃脱的非常,它会直接到控制台,有了J2SE5.0的Excecutor就可以在每一个线程上附着一个异常处理器,用线程对象的setUncaughtException方法进行设置。

7. 对于共享资源的非原子操作,可能会导致数据不同步,可用synchronized关键字解决,实现同步,同时,java.util.concurrency包也提供了一些Lock类用于解决此类问题,在原子操作前后加解锁。有lock和tryLock方法可分别实现阻塞和非阻塞式加锁。

8. 原子性可以应用于除long和double之外的所有基本类型的简单操作上。但尽量避免依赖原子性操作去控制并发,因为很多看似简单的操作,实际上并非原子操作如++和--等。

9. 有时,你只希望防止多个线程同时访问方法内的某段代码而不是防止访问整个方法,该段代码称临界区,它也使用synchronized关键字建立 。当然也可以用lock对象也创建临界区。synchronized(this){...}表示在不同线程中用同一对象时,不可同时访问该对象的该块代码。

10. synchronized可用于任何对象上达到同步的效果。也就是加了锁。

11. 防止任务在共享资源上冲突的另一种方式是线程本地化,由java.lang.ThreadLocal类实现。是一种自动化机制,可以为使用相同变量的每个不同的线程都创建一个副本。

12. 一个线程可处于的状态有四个:新建,就绪,阻塞,死亡。线程阻塞的几个原因为:

(1)调用了sleep();

(2)使用了wait()挂起线程,直到收到其它线程的notify()或notifyAll()时才会重新成为就绪;

(3)任务在等待某个输入/输出完成;

(4)申请互斥资源未成功时。

13. IO阻塞和synchronized引起的阻塞不可中断,对于I/O阻塞,可以关闭其底层资源(如文件)的方式中断,而synchronized引起的阻塞若改用ReentrantLock实现则可被中断。

14. 线程之间协作完成某任务时,wait用于等待资源,notify用于释放资源。调用sleep与yield并不会释放线程拥有的锁,但wait会释放。

15. 连接池的一种实现:实现了Runnable的线程类定义一些静态任务列表,用来存储待完成的任务。任务调度程序创建若干线程实例,并且往线程类的静态列表中添加任务,线程实例的run中定义为互斥地访问任务列表中的任务并一个个取出执行。主要用到各子线程共享static类变量这一特点,同时用synchronized和notifyAll实现互斥访问。

16. 消费者生产者程序,一般用两种加锁,如生产者在等空间时对自己加锁,在生产并填入空间时对等在上面的消费者notifyAll()。而消费者在等产品时对自己加锁,在消费完食品后,对等等在空间的生产者notifyAll()。能成功的原因在于while(resterant==null)wait();wait操作会释放张璐上的锁。示例代码如下:

 

17. 用BlockingQueue可以忽略同步问题,生产者往其中put,消费者从中take就可以了。BlockingQueue是一个接口,它有很多实现,常见的有LinkedBlockingQueue,ArrayBlockingQueue,定义如:

 

18. 两个任务之间通信,还可以用管道进行。Java提供了PipedWriter与PipedReader类供调用。

19. PriorityBlockingQueue队伍中的任务是按优先级排序的,任务需要实现Comparable接口。用来比较两个对象的优先级。

20. 在读多写少的情况下,应采用乐观加锁的方式提高效率。即所有工作先在一个副本中进行,完成之后进行修改时再加锁。因写少,所以加锁一般没有冲突。如Java提供的ReadWriteLock。Java也提供不少免锁容器提高效率。

21. synchronized实现机制,也即可锁的机制:(1)synchronized修饰方法表该类只能一个实例调用该方法,修饰static方法时表示不能多个线程访问该方法,此时加的是类上的锁。(2)synchronized (this)表在对象上加锁。synchronized关键字是不会继承到子类中的,系统处理并发开销很大,不是必要时,不要随便用。(4)每个对象只有一个锁与之关联,synchronized的作用仅仅是获得锁,作用域后或调用了wait()会释放该锁。需要注意的是:1.变更尽量不要用public或protected的,以免绕过方法直接修改变量,无法控制同步;2.JVM底层用管程实现synchronized,管理即是synchronized修饰的那段代码;3. 有wait和nitify的地方一定有synchronized,因为wait和notify方法是属于某个对象的,必须取得对象上的锁方可调用。

抱歉!评论已关闭.