Think in Java——并发

来源:互联网 发布:传智播客java 2016 编辑:程序博客网 时间:2024/04/26 17:56

Java SE5,提供了java.util.concurrent包,里面提供了各种关于并发操作的类,并且推荐取代以前的Thread方式。个人认为,对于一般的多线程而言,Thread已经足够了,只有在大型的系统级应用频繁并发时,才需要用到,但是这个包确实很强大,很安全。

Thread.sleep()是可中断(interrupt)的,I/O和synchronized是不可中断的阻塞。对于这类阻塞,一个简单的方法是关闭任务在其上发生阻塞的底层资源,如socket流等,但是PipedIO是个例外,可以中断。

 

安全中止线程,分为 线程在阻塞状态和非阻塞状态。

1.阻塞状态,抛出异常中止线程;

2.非阻塞状态,跳出循环直接中止;

都需要在finally块中做回收资源的操作,如果要安全中止线程,需要考虑到这两种情况,并且给出两种相应的中断后的处理机制,否则会出现不可预测的问题。

package Executor;import java.util.concurrent.*;import static net.mindview.util.Print.*;class NeedsCleanup { private final int id; public NeedsCleanup(int ident) {  id = ident;  print("NeedsCleanup " + id); } public void cleanup() {  print("Cleaning up " + id); }}class Blocked3 implements Runnable { private volatile double d = 0.0; public void run() {  try {   while (!Thread.interrupted()) {    // point1    NeedsCleanup n1 = new NeedsCleanup(1);    // Start try-finally immediately after definition    // of n1, to guarantee proper cleanup of n1:    try {     print("Sleeping...");     TimeUnit.SECONDS.sleep(3);     // point2     NeedsCleanup n2 = new NeedsCleanup(2);     // Guarantee proper cleanup of n2:     try {      print("Calculating");      // A time-consuming, non-blocking operation:      for (int i = 1; i < 250000000; i++)       d = d + (Math.PI / Math.E) / d;      print("Finished time-consuming operation");     } finally {      n2.cleanup();     }    } finally {     n1.cleanup();    }   }   print("Exiting via while() test");  } catch (InterruptedException e) {   print("Exiting via InterruptedException");  } }}public class InterruptingIdiom { public static void main(String[] args) throws Exception {    Thread t = new Thread(new Blocked3());  t.start();  TimeUnit.MILLISECONDS.sleep(new Integer(3100));//change this to test  t.interrupt(); }}

在Java SE5中添加了各种线程安全的容器类,可以用来消除加锁,这些免锁容器的通用策略是:对容器的修改可以与读取操作同时发生,只要读取者只能看到完成修改的结果即可,修改是在容器数据结构的某个部分(或者完整)的一个单独的副本上执行的,并且这个副本在修改过程中不可视。只有当修改完成时,被修改的结构才会自动得与主数据结构进行交换,之后reader就可以看到这个修改了。如 CopyOnWriteArrayList、CopyOnWriteArraySet、ConcurrentHashMap、ConcurrentLinkedQueue比起synchronized 容器获得更好的效率。

synchronized方法和synchronized块的意义是相同的,加锁对象,synchronized(this),表明这个类里面其他的同步方法都会被阻塞,而非同步方法可以执行。Thread.sleep()是属于线程的方法,不触及锁的释放,而wait(),notify()/notifyAll()是属于Object的方法,wait()操作会释放锁(对象)。

synchronized比Lock类效率低,但是代码更直观,ReadWriteLock对有大量Reader极少数Writer的情况进行了优化,在write过程中,其他线程不得读写。这些只有当你试图提高性能的时候才应该想到,因为都很复杂。

多线程并发总是会产生各种意想不到的问题,因此,是否可以寻求一种替代逻辑呢?活动对象!android 中的handler好像就是这种机制,android的UI是线程不安全的因此不能在主线程之外更新UI,所以通过挂载在主线程上的handler来更新。

 

 

 

小鸟刚来,请各位大神多多指教,O(∩_∩)O谢谢!!!