`

【线程】线程并发的一些高级API

    博客分类:
  • Java
 
阅读更多

Lock&Condition

 

Executor

任务执行器,通过线程池来完成任务的执行。

使用线程池的好处:

仅需维护一定数量的线程去执行任务,降低频繁创建或销毁线程而带来的性能损耗。

 

interface ExecutorService extends Executor

interface ScheduledExecutorService extends ExecutorService

 

Executor  属于顶层接口,仅提供了一个执行线程任务的方法

void execute(Runnable command);

 

ExecutorService 接口则定义了更多适用的方法

 <T> Future<T> submit(Callable<T> task);

 <T> Future<T> submit(Runnable task, T result);

 <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks);//批量任务

 

 

创建线程池,使用Executors

//1.单一线程

ExecutorService executor = Executors.newSingleThreadExecutor();

//2.可无限创建新线程,一般用于请求多但处理时间短的情况

ExecutorService executor = Executors.newCachedThreadPool();

//3.固定线程数量的线程池

ExecutorService executor = Executors.newFixedThreadPool(nThreads);

 

//4. 按指定频率执行任务的线程池

ScheduledExecutorService service = Executors.newScheduledThreadPool(corePoolSize);

 

扩展:

手动配置线程池的参数

ExecutorService executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);

 

Callable & Future 的用法

package org.thread;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadLocalRandom;

public class App {
	
	ExecutorService executor = Executors.newSingleThreadExecutor();
	ArchiveSearcher searcher = new ArchiveSearcher();

	void showSearch(final String target) throws InterruptedException {
		//提交任务1到线程池中执行
		Future<String> future = 
			executor.submit(new Callable<String>() {
				@Override
				public String call() throws Exception {
					return searcher.search(target);
				}
		});
		
		//任务2由当前线程负责执行
		displayOtherThings();
		
		//当任务2执行完成后,当前线程尝试获取任务1的执行结果
		try {
			disPlayText(future.get());
			executor.shutdown();
		} catch (ExecutionException e) {
			e.printStackTrace();
			cleanup();
			return;
		}
	}

	private void cleanup() {
		executor.shutdownNow();
	}

	private void disPlayText(String text) {
		System.out.println("Result from future is :" + text);
	}

	private void displayOtherThings() {
		for(int i=0;i<10;i++) {
			System.out.println(Thread.currentThread().getName() + "..." + i);
		}
	}

	public static void main(String[] args) throws InterruptedException {
		new App().showSearch("UFO");
	}
}

class ArchiveSearcher {
	public String search(String target) {
		int mills = ThreadLocalRandom.current().nextInt(10000);
		System.out.format(Thread.currentThread().getName() + " sleep %s ms%n", mills);
		try {
			Thread.sleep(mills);
		} catch (InterruptedException e) {}
		return "Hello Callable & Future! The target is: " + target;
	}
}

 

任务调度

package schedulePool;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class ThreadScheduledTest {
	/**
	 * 线程调度中,同一时间段内只能有1个任务被调度.
	 * 如果前面的任务抛出了异常,后面的调度将不会再执行!
	 */
	public static void main(String[] args) throws Exception {
		ScheduledExecutorService executor = Executors.newScheduledThreadPool(5);
		System.out.println("start at: "+System.currentTimeMillis());
		
		/**
		 * AtFixedRate调度的基本规则:
		 * 		initialDelay之后开启第1个任务的调度
		 * 		第二个调度:initialDelay+period, 
		 * 		then initialDelay + 2 * period,
		 * 		...
		 * 需要注意的是:
		 * 	前一个任务执行所需时间大于period值时,Executor不会按period值调度下一个任务,
		 * 	而是等到前一个任务完成之后立即开始调度下一个任务
		 *  但,一般情况下线程调度的执行周期都是比较长的值,如1天执行1次
		 */
		executor.scheduleAtFixedRate(new Runnable() {
			@Override
			public void run() {
				long current = System.currentTimeMillis();
				System.out.println(Thread.currentThread().getName()+": " + current);
				try {
					Thread.sleep(4000);
				} catch (InterruptedException e) {}
				System.out.println(Thread.currentThread().getName()+": " + "Done "+System.currentTimeMillis());
			}
		}, 2, 3, TimeUnit.SECONDS);
		
		/**
		 * 以上一个任务完成的时间为计算基准,在此基础上延迟若干秒后才开始新的调度
		 * 前一个任务完成后 + delay ===> 开始调度下一个任务
		 */
		executor.scheduleWithFixedDelay(new Runnable() {
			@Override
			public void run() {
				long current = System.currentTimeMillis();
				System.out.println(Thread.currentThread().getName()+": " + current);
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {}
				System.out.println(Thread.currentThread().getName()+": " + "Done "+System.currentTimeMillis());
			}
		}, 2, 3, TimeUnit.SECONDS);
	}
}

 

 

 

并发集合

java.util.concurrent提供了一些集合框架的辅助类

BlockingQueue 任务列队

ArrayBlockingQueue LinkedBlockingQueue

ConcurrentMap

HashMap的并发模式:ConcurrentHashMap

TreeMap的并发模式:ConcurrentSkipListMap

 

对这些集合中的元素进行操作,会发生happens-before关系,能够有效避免内存一致性错误

 

原子操作

 

class Sequencer {
	
	private final AtomicLong sequenceNumber = new AtomicLong(0);

	public long next() {
		return sequenceNumber.getAndIncrement();
	}
}

 

分享到:
评论

相关推荐

    WEBAPI多线程并发测试工具

    标题"WEBAPI多线程并发测试工具"指出,这是一个专门针对Web API进行多线程并发测试的工具。Web API通常指的是应用程序接口,它们允许不同的服务之间进行通信,以实现数据交换和功能整合。多线程并发测试则是验证在多...

    Java 模拟线程并发

    在Java中,线程并发可以通过多种方式实现,包括继承Thread类、实现Runnable接口以及使用ExecutorService和Future等高级API。下面将详细探讨这些知识点。 首先,Java中创建线程主要有两种方法。一种是通过继承Thread...

    多线程,高并发.zip

    另外,Java并发API(java.util.concurrent包)提供了一系列高级并发工具,如`ConcurrentHashMap`(线程安全的哈希映射)、`BlockingQueue`(阻塞队列)和`Future`(异步计算结果)。这些工具可以帮助开发者更好地...

    java线程与并发编程实践

    本书《java线程与并发实践编程》由Jeff Friesen撰写,2017年2月出版,提供了关于Java线程API和并发工具的详细指南,帮助开发者深入理解和应用这些关键概念。 首先,Java线程是程序执行的独立路径,每个线程都有自己...

    易语言 API线程等待

    多线程是指在一个进程中同时运行多个线程,以提高程序的并发性和效率。然而,多线程编程中经常需要控制线程的执行顺序,确保某些线程完成特定任务后再继续其他线程的工作,这就是线程等待的作用。 API线程等待,...

    易语言 API线程操作

    API线程允许程序员在易语言环境中调用操作系统级别的线程功能,实现并发执行任务,提高程序的响应速度和执行效率。 API线程的操作主要涉及以下几个方面: 1. **线程创建**:在易语言中,通过API函数`CreateThread`...

    windows API 线程的创建

    线程是操作系统调度的基本单位,它允许程序并发执行不同的任务,从而提高系统资源的利用率和程序的响应速度。Windows API提供了`CreateThread`函数,用于创建新的线程。该函数定义如下: ```cpp HANDLE ...

    Tesseract OCR多线程并发识别案例

    在处理大量图像或需要快速响应时间的应用场景中,多线程并发识别可以显著提升效率。以下将详细介绍如何利用Tesseract OCR实现多线程并发识别,以及可能涉及的相关技术点。 首先,理解Tesseract OCR的基本工作原理是...

    基于Qt的多线程并发服务器

    "基于Qt的多线程并发服务器"是一个典型的解决方案,它利用了Qt库的强大功能,特别是其对多线程的支持,来处理来自多个客户端的并发请求。下面我们将深入探讨这个主题。 首先,Qt是一个跨平台的应用程序开发框架,...

    Java 多线程与并发编程总结.doc

    此外,Java 5引入了`java.util.concurrent`包,包含如`ExecutorService`, `Future`, `Callable`, `Semaphore`, `CyclicBarrier`, `CountDownLatch`等高级并发工具类,这些工具极大地简化了多线程编程。 在并发编程...

    并发编程实践,全面介绍基础知识、JVM同步原语、线程安全、低级并发工具、线程安全容器、高级线程协作工具、Executor部分等

    - **Java并发演进历史**:从Java 1.0的Thread类到Java 5引入的并发包`java.util.concurrent`,再到Java 7和8的改进,Java并发API不断发展,提供了更多高效、易用的并发工具。 - **Java并发模型**:Java并发模型...

    VB使用API做的稳定多线程例程

    在VB(Visual Basic)编程中,多线程是一种高级技术,允许程序同时执行多个独立的任务。这个"VB使用API做的稳定多线程例程"是一个示例,展示了如何利用API函数在VB环境中创建和管理多线程。API(应用程序编程接口)...

    java线程api学习文档

    `Thread`类是创建和管理线程的基础,而`java.util.concurrent`包提供了一些高级并发工具,如线程池、并发集合等,帮助开发者更有效地管理和同步线程。 1. **线程的创建与启动**: - 创建线程有两种方式:通过继承`...

    黑马程序员_张孝祥_Java多线程与并发库 视频+代码+资料

    5. **并发容器**:Java并发库还提供了一些线程安全的集合类,如`ConcurrentHashMap`、`CopyOnWriteArrayList`等,这些容器可以在高并发场景下安全地使用。 通过以上知识点的学习,开发者可以深入理解Java多线程编程...

    Windows下线程的创建和并发执行.rar_Windows下线程的创建和并发执行_多线程并发_线程创建_线程并发_获得操作系统

    编写一个程序,完成多个...通过本实验,学习在Win32程序中利用操作系统提供的API创建线程,并通过所创建线程的运行情况来获得关于多线程并发的感性认识,以及加深对临界资源(本实验中临界资源是屏幕)互斥访问的理解。

    server_thread.rar_多线程socket_并发

    标题“server_thread.rar_多线程socket_并发”提示我们,这个压缩包中包含了一个使用Unix操作系统下Socket API实现的并发服务器程序,它利用了多线程技术来提高服务的并行处理能力。接下来,我们将深入探讨多线程...

    Windows下基于socket多线程并发通信的实现

    Socket 接口是TCP/IP 网络最为通用的应用接口,也是在Internet 上进行网络程序应用开发最通用的API[1],本文介绍了Socket通信的基本机制以及采用多线程技术实现并发通信的基本原理,并给出实例。

    Win32 API多线程编程例程

    【Win32 API多线程编程】是一种在Windows操作系统中实现并发执行任务的技术。通过创建多个线程,程序可以同时处理多个任务,提高系统效率。然而,多线程编程也存在挑战,比如线程间资源竞争和同步问题。 在Windows...

Global site tag (gtag.js) - Google Analytics