java编程思想阅读笔记(十一)并发

继续把笔记整理着。并发多线程的东西说起来就很多了,如果说复杂,要是线程之间的交集较多的话(交互啊,共享资源等等),确实很棘手,而且往往测试还是个大问题,再扯上性能稳定之类云云就。。。;如果说处理的逻辑清晰简单,那么它也挺简单的,似乎只要实现Runable接口,并通过Thread类或者Executor接口(Executor、ExecutorService)管理就好了;个人的感觉首先把逻辑、状态转换、交互理清了,后续会少很多麻烦的。


1.基本线程机制
(1)首先谈Runnable接口,可以看到其本身只有一个run方法,在类的run方法中开启另一个线程。而为了想对创建的线程增加些管理的功能,可以使用Thread类(实现了Runnable,因此可以继承Thread而覆盖run方法)。看看几个方法:
start(),使该线程开始执行,但是不能多次启动
sleep(long millis),静态方法,是线程休眠指定的毫秒数
getPriority() ,setPriority(int newPriority) 获得和设定线程的优先级,当然只有MAX_PRIORITY ,MIN_PRIORITY,NORM_PRIORITY三种
setDaemon(boolean on),使线程变为后台(守护)线程
join(),等待线程终止
还有判断是否中断等等,当然可以查看手册,但是发现这种多线程的方法是没有返回值的,可以有异常;
(2)Callable<V>接口,可以给你带回想要的返回值泛型V,但是必须使用ExecutorService.submit( );这里有个疑问是为什么Runnable接口是在java.lang的包中的,而Callable<V>在java.util.concurrent包中。
(3)在java.util.concurrent包中的ExecutorService,实现了Executor接口,想想看看线程池

ExecutorService exec = Executors.newCachedThreadPool() 或者FixedThreadPool()


2.共享受限资源

对于多个线程或进程共享受限的资源,可以通过加锁的方式,lock(检查锁是否可用,否阻塞;是获取锁执行,释放锁),trylock(尝试获取锁,可以获得则执行,否则直接返回);另一种方式就是给需要共享的代码加上Synchronized关键字,类似于锁定;从书中后面的从性能角度分析的,显示地使用lock更稳定,而Synchronized在较少而且简单的情况下才好些(那为什么要搞出这么一个关键字?为了更抽象和简单?因为lock和trylock在c中是很常用的方式,至于什么互斥量、信号量的我就不写了,因为和C中的似乎没有区别)。而对于受限资源的访问老是有个死锁的问题,只要避免那四个条件同时发生:资源的互斥访问(资源至少有一个是非共享的),有等待,访问资源构成循环,而且互相之间不能抢占;说的不严谨,其实意思就是当多个线程或进程访问一些资源时,如果这些资源存在至少一个是非共享的,那么当一个线程拥有一个资源等待另一个非共享的资源而阻塞时,另一个线程拥有这个非共享资源而等待被其它线程使用的非共享资源(或者等待其它想要这个非共享资源的线程运行完毕),而且不能抢占资源,造成了相互等待而不能运行的结局。


3.简单的提到一下新类库中的构件。CountDownLatch:同步一个或多个任务,强制它们等待由其它任务执行的一组操作完成(而且是只触发一次事件),CyclicBarrier:多个任务一致向前执行。
4.线程之间的协作,其实上面的锁啊,信号量啊,新构件啊就是一些方式;然后呢,还有些wait——notify notifyAll()
interrupt()——Thread.interrupted()的方法;这里也有C中经常用到的signal()的。
我这里只是把一些看到的,可能用的到的概念之类的提到,但是具体的使用只有在真正用到的时候才能发挥它的力量。我自己是感觉用的不多的话,多做练习似乎只能加深些印象,时间长了不用还是会忘;而对于真正的协作,性能,稳定的说法就只能说说了。

你可能感兴趣的:(java编程思想)