Thread

1. 无论何种方式,启动一个线程,就要给它一个名字!这对排错诊断系统监控有帮助。否则诊断问题时,无法直观知道某个线程的用途。

2. 程序应该对线程中断作出恰当的响应。

3. ThreadLocal

local variable(线程局部变量)。它的功用非常简单,就是为每一个使用该变量的线程都提供一个变量值的副本,是每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突。从线程的角度看,就好像每一个线程都完全拥有该变量。

注意:使用ThreadLocal,一般都是声明在静态变量中,如果不断的创建ThreadLocal而且没有调用其remove方法,将会导致内存泄露。

4、任务的提交者和执行者

为了方便并发执行任务,出现了一种专门用来执行任务的实现,也就是Executor。由此,任务提交者不需要再创建管理线程,使用更方便,也减少了开销。

java.util.concurrent.Executors是Executor的工厂类,通过Executors可以创建你所需要的Executor。有两种任务:RunnableCallable。Callable是需要返回值的任务。

Task Submitter把任务提交给Executor执行,它们之间需要一种通讯手段,这种手段的具体实现,通常叫做Future。Future通常包括get(阻塞至任务完成),cancel,get(timeout)(等待一段时间)等等。Future也用于异步变同步的场景。


    ExecutorService executorService = Executors.newSingleThreadExecutor();
    Callable<Object> task = new Callable<Object>() {
        @Override
        public Object call() throws Exception {
            Thread.sleep(1000);
            return "222";
        }
    };
    Future<Object> future = executorService.submit(task);
    try {
       //future.get(3, TimeUnit.SECONDS); //等待三秒后超时,表示执行失败
       if(!future.cancel(true)){
            System.out.println(future.get());
        }
    } catch (InterruptedException | ExecutionException e) {
        System.out.println("execute failed");
        e.printStackTrace();
    }
    System.out.println("sth");

5、阻塞队列

阻塞队列,是一种常用的并发数据结构,常用于生产者-消费者模式。

在Java中,有三种常用的阻塞队列:

ArrayBlockingQueue、LinkedBlockingQueue、SynchronousQueue

blockingQ.put(object);// 如果队列满则阻塞

blockingQ.take(); // 如果队列空则阻塞

blockingQ.poll(2, TimeUnit.SECONDS); //防止死等

6、要执行wait操作,必须先取得该对象的锁。执行wait操作之后,锁会释放。被唤醒之前,需要先获得锁。


synchronized (xxxx)  {
   xxxx.wait();
}


要执行notify和notifyAll操作,都必须先取得该对象的锁。


synchronized (xxxx)  {
   xxxx.notify();
}


未取得锁就直接执行wait、notfiy、notifyAll会抛异常IllegalMonitorStateException。

7、ReentrantLockSynchronized

Synchronized是Lock的一种简化实现,一个Lock可以对应多个Condition,而synchronized把Lock和Condition合并了,一个synchronizedLock只对应一个Condition,可以说Synchronized是Lock的简化版本。

不要在Lock和Condition上使用wait、notiffy、notifyAll方法,而是使用如下对应的方法。

awati-> wait

singal-> notify

singalAll-> notifyAll

8、Java.util.concurrent中实现的原子操作类包括:AtomicBoolean、AtomicInteger、AtomicLong、AtomicReference。

9、ForkJoinPool

ForkJoinPool 是 Java SE 7 新功能“分叉/结合框架”的核心类。分叉/结合框架是一个比较特殊的线程池框架,专用于需要将一个任务不断分解成子任务(分叉),再不断进行汇总得到最终结果(结合)的计算过程。

子任务由 ForkJoinTask 的实例来代表。它是一个抽象类,JDK 为我们提供了两个实现:RecursiveTask 和 RecursiveAction,分别用于需要和不需要返回计算结果的子任务。ForkJoinTask 提供了三个静态的 invokeAll 方法来调度子任务,注意只能在 ForkJoinPool 执行计算的过程中调用它们。

以下代码计算磁盘指定目录里的子文件数


package xjt.thread;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;
public class CountFileTaskRecursive extends RecursiveTask<Integer> {
    private static final long serialVersionUID = 1L;
    int sum = 0;
    File file;
    public CountFileTaskRecursive(File file) {
       this.file = file;
    }
    @Override
    protected Integer compute() {
    Integer csum = 0;
    List<CountFileTaskRecursive> tasklist = new ArrayList<CountFileTaskRecursive();
    if (file.isDirectory()){
        for (File f : file.listFiles()){
            CountFileTaskRecursive t = new CountFileTaskRecursive(f);
            tasklist.add(t);
        }
    } else{
        csum++;
            }
    if (!tasklist.isEmpty()){
        for (CountFileTaskRecursive t : invokeAll(tasklist)){
            csum += (Integer) t.join();
        }
    }
    return csum;
    }
    public static void main(String[] args) {
    CountFileTaskRecursive task = new CountFileTaskRecursive(new File("F:/soft"));
    Integer sum = (Integer) new ForkJoinPool().invoke(task);
    System.out.println(sum);
    }
}

10、CountDownLatch

 Java的concurrent包里面的CountDownLatch其实可以把它看作一个计数器,只不过这个计数器的操作是原子操作,同时只能有   一个线程去操作这个计数器,也就是同时只能有一个线程去减这个计数器里面的值。你可以向CountDownLatch对象设置一个初始的数字作为计数值,任何调用这个对象上的await()方法都会阻塞,直到这个计数 器的计数值被其他的线程减为0为止。

参见http://zapldy.iteye.com/blog/746458

11、ConcurrentHashMap
参见http://www.infoq.com/cn/articles/ConcurrentHashMap

12、Thread.join()
public final void join() throws InterruptedException Waits for this thread to die. Throws: InterruptedException - if any thread has interrupted the current thread. The interrupted status of the current thread is cleared when this exception is thrown.
参见http://my.oschina.net/zyc1016/blog/138581

你可能感兴趣的:(java,thread,executorService,ForkJoinPool)