并发学习笔记(更新中,java编程思想第四版21章)

实现并发最直接的方式是在操作系统级别使用进程。

 

并发任务彼此隔离的编程语言,被称为函数型语言,例如:erlang。

 

Java的线程机制是抢占式的,这表示调度机制会周期性地中断线程,将上下文切换到另一个线程,从而为每个线程都提供时间片,使得每个线程都会分配到数量合理的时间去驱动它的任务。(协作多线程)

 

线程的底层机制:切分CUP时间,但通常你不需要考虑它。

使用线程机制是一种建立透明的,可扩展的程序的方法。

 

Thread.yield()的调用是对线程调度器的一种建议,它表明“我已经执行完全生命周期中最重要的部分,此刻正是切换给其他任务执行一段时间的大好时机。

main()创建Thread对象时,每个Thread都”注册“了自己,它的任务退出其run()并死亡之前,垃圾回收器无法清除它。一个线程会创建一个单独的执行线程,在对start()的调用完成之后,它仍会继续存在。

 

使用Executor(java.util.concurrent包),用于管理Thread对象,为客户端和任务执行之间提供一个间接层,由Executor这个中介对象负责执行任务。允许你管理异步任务的执行。

ExecutorService(具有服务生命周期的Executor)知道如何构建恰当的上下文来执行Runnable对象。

		ExecutorService service = Executors.newCachedThreadPool();//or newFixedThreadPool(5_
		for(int i = 0; i < 5; i++){
			service.execute(new LiftOff());
		}
		service.shutdown();

 创建Executor的线程(这里是main线程)会继续运行,直至Executor的shutdown()方法调用后,这个线程(main)将在Executor中所有任务完成之后尽快退出。

 

在任何线程池中,现有线程在可能的情况下,都会被自动复用。

SingleThreadExecutor:对于想在另一个线程中连续运行的任何事物来说,是很有用的。例如监听进入的套接字连接的任务,或希望在线程中运行的短任务(如更新本地或远程日志的小任务)。

 

从任务中产生返回值:Callable接口。它的类型参数表示是从方法call()中返回值,并且必须使用ExecutorService.submit()方法调用它,示例:

public class CallableDemo {
	public static void main(String[] args) {
		ExecutorService service = Executors.newCachedThreadPool();
		List<Future<String>> list = new ArrayList<Future<String>>();
		
		for(int i =0; i < 5; i++){
			list.add(service.submit(new TaskWithResult(i)));
		}
		
		for(Future<String> future : list){
			try{
				//get() blocks until completion:
			System.out.println(future.get());
			}catch(Exception e){
				e.printStackTrace();
			}finally{
				service.shutdown();
			}
		}
	}
	
}

class TaskWithResult implements Callable<String> {
	private int id;

	public TaskWithResult(int id) {
		this.id = id;
	}

	@Override
	public String call() throws Exception {
		return "result  of TaskWithResult " + id;
	}
}

异常是不能跨线程传播回main(),必须在本地处理所有任务内部产生的异常。

 

优先级将该线程的重要性传递给了调度器。优先级较低的线程仅仅是执行的频率较低。试图通过设置优先级来调试线程运行顺序是不可靠的。

 

让步:yield(),让别的线程使用CPU。这只是一个暗示,没有任何机制保证它将会被采纳。

 

后台线程:指在程序运行的时候在后台提供一种通用服务的线程,并不属于程序中必要的部分。因此当非后台进程结束时,程序也会终止,同时会杀死进程中的所有后台线程。反过来,只要有非后台线程还在运行,程序就不会终止(如main是非后台线程)。

可以通过实现ThreadFactory来定制Executor创建的线程属性(后台,优先级,名称):

 

 

 

 

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