文档章节

Thread

xiejuntao
 xiejuntao
发布于 2013/04/06 17:13
字数 1186
阅读 194
收藏 3

<p>1. 无论何种方式,启动一个线程,就要给它一个名字!这对排错诊断系统监控有帮助。否则诊断问题时,无法直观知道某个线程的用途。 <p>2. 程序应该对线程中断作出恰当的响应。 <p> 3. **ThreadLocal** <br>local variable(线程局部变量)。它的功用非常简单,就是为每一个使用该变量的线程都提供一个变量值的副本,是每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突。从线程的角度看,就好像每一个线程都完全拥有该变量。 <br>注意:使用ThreadLocal,一般都是声明在静态变量中,如果不断的创建ThreadLocal而且没有调用其remove方法,将会导致内存泄露。 <p>4、任务的提交者和执行者 <br>为了方便并发执行任务,出现了一种专门用来执行任务的实现,也就是Executor。由此,任务提交者不需要再创建管理线程,使用更方便,也减少了开销。 <br>java.util.concurrent.Executors是**Executor**的工厂类,通过**Executors**可以创建你所需要的Executor。有两种任务:**Runnable**、**Callable**。Callable是需要返回值的任务。 <br>Task Submitter把任务提交给Executor执行,它们之间需要一种通讯手段,这种手段的具体实现,通常叫做**Future**。Future通常包括get(阻塞至任务完成),cancel,get(timeout)(等待一段时间)等等。Future也用于异步变同步的场景。

<!-- lang: java -->
	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");

<p>5、阻塞队列 <br>阻塞队列,是一种常用的并发数据结构,常用于生产者-消费者模式。 <br>在Java中,有三种常用的阻塞队列: <br>ArrayBlockingQueue、LinkedBlockingQueue、SynchronousQueue <br>blockingQ.put(object);// 如果队列满则阻塞 <br>blockingQ.take(); // 如果队列空则阻塞 <br>blockingQ.poll(2, TimeUnit.SECONDS); //防止死等 <p>6、要执行wait操作,必须先取得该对象的锁。执行wait操作之后,锁会释放。被唤醒之前,需要先获得锁。

<!-- lang: java -->
synchronized (xxxx)  {
   xxxx.wait();
}

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

<!-- lang: java -->
synchronized (xxxx)  {
   xxxx.notify();
}

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

<p>7、**ReentrantLock**和**Synchronized** <br>Synchronized是Lock的一种简化实现,一个Lock可以对应多个Condition,而synchronized把Lock和Condition合并了,一个synchronizedLock只对应一个Condition,可以说Synchronized是Lock的简化版本。 <br>不要在Lock和Condition上使用wait、notiffy、notifyAll方法,而是使用如下对应的方法。 <br>awati-> wait <br>singal-> notify <br>singalAll-> notifyAll <p>8、Java.util.concurrent中实现的原子操作类包括:AtomicBoolean、AtomicInteger、AtomicLong、AtomicReference。 <p>9、**ForkJoinPool** <br>ForkJoinPool 是 Java SE 7 新功能“分叉/结合框架”的核心类。分叉/结合框架是一个比较特殊的线程池框架,专用于需要将一个任务不断分解成子任务(分叉),再不断进行汇总得到最终结果(结合)的计算过程。 <br>子任务由 ForkJoinTask 的实例来代表。它是一个抽象类,JDK 为我们提供了两个实现:RecursiveTask 和 RecursiveAction,分别用于需要和不需要返回计算结果的子任务。ForkJoinTask 提供了三个静态的 invokeAll 方法来调度子任务,注意只能在 ForkJoinPool 执行计算的过程中调用它们。 <br>以下代码计算磁盘指定目录里的子文件数

<!-- lang: java -->
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

© 著作权归作者所有

共有 人打赏支持
xiejuntao
粉丝 6
博文 27
码字总数 18349
作品 0
广州
程序员
【python 多线程 local 线程本地数据】local 线程本地数据

线程(run 方法) 之外的变量,多个线程竞争会有临界点问题,需要注意(如 worker3 就存在多个线程操作sum ,引起错乱) 线程(run 方法) 之内的变量,为单个线程独立所拥有 (如worker2) 线...

_______-
10/06
0
0
刚把 nutch2.2 成功跑起来了,为什么没抓的有数据呢???

nohup.out 文件内容 ,没有报错,往大神些随便指点下 InjectorJob: Using class org.apache.gora.memory.store.MemStore as the Gora storage class. InjectorJob: total number of urls re......

jack_peng
2013/09/24
2.2K
1
多线程和CPU多核的问题

我电脑是四核的,我做了一个测试,开启两个线程,一个每一秒执行一次,一个每两秒执行一次,因为电脑是四核的,所以我预想的结果是两个线程可以同时执行,互不干涉。但是结果却不是这样的,从...

王大叔爱编程
2014/12/01
665
1
Thread和Runnable简介(转)

转自:http://www.cnblogs.com/skywang12345/p/3479063.html Thread和Runnable简介 Runnable 是一个接口,该接口中只包含了一个run()方法。它的定义如下: Runnable的作用,实现多线程。我们...

addcn
2015/12/21
23
0
聊聊reactive streams的schedulers

序 本文主要研究一下reactive streams的schedulers 背景 默认情况下Mono以及Flux都在主线程上运行,有时候可能会阻塞主线程,可以通过设定schedulers让其在其他线程运行。 原始输出 没有使用...

go4it
01/15
0
0

没有更多内容

加载失败,请刷新页面

加载更多

linux 系统的运行级别

运行级别 运行级别 | 含义 0 关机 1 单用户模式,可以想象为windows 的安全模式,主要用于修复系统 2 不完全的命令模式,不含NFS服务 3 完全的命令行模式,就是标准的字符界面 4 系统保留 5 ...

Linux学习笔记
55分钟前
1
0
学习设计模式——命令模式

任何模式的出现,都是为了解决一些特定的场景的耦合问题,以达到对修改封闭,对扩展开放的效果。命令模式也不例外: 命令模式是为了解决命令的请求者和命令的实现者之间的耦合关系。 解决了这...

江左煤郎
今天
2
0
字典树收集(非线程安全,后续做线程安全改进)

将500W个单词放进一个数据结构进行存储,然后进行快速比对,判断一个单词是不是这个500W单词之中的;来了一个单词前缀,给出500w个单词中有多少个单词是该前缀. 1、这个需求首先需要设计好数据结...

算法之名
昨天
10
0
GRASP设计模式

此文参考了这篇博客,建议读者阅读原文。 面向对象(Object-Oriented,OO)是当下软件开发的主流方法。在OO分析与设计中,我们首先从问题领域中抽象出领域模型,在领域模型中以适当的粒度归纳...

克虏伯
昨天
0
0
Coding and Paper Letter(四十)

资源整理。 1 Coding: 1.Tomislav Hengl撰写的非官方作者指南:Michael Gould•Wouter Gerritsma。 UnofficialGuide4Authors 2.R语言包rwrfhydro,社区贡献的工具箱,用于管理,分析和可视化...

胖胖雕
昨天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部