java.util.concurrent 并发工具包(二)

一、ThreadPoolExecutor 线程池执行者

  • 初始化线程池的参数
corePoolSize核心线程大小
maximumPoolSize最大线程大小
keepAliveTime空余的多余线程保持时间
unit时间单位
workQueue阻塞队列
handler拒绝服务助手
  • 线程池内部运行机制

1、当有任务委托给线程池,若池中线程数量 < 核心线程数量,则创建新的线程,即使有空闲线程。

2、若核心线程数量已满,且没有空闲,则把任务放入阻塞队列

3、若核心线程阻塞队列都没有空闲,此时再来任务,则判断当前池内线程数量是否 < 最大线程数量。若小于则创建临时线程去处理该任务。

4、若核心线程阻塞队列临时线程都已经到达上限,且被占用。此时再来任务,则由拒绝助手去处理。

  • 代码示例
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class ThreadPoolExecutorDemo {

	public static void main(String[] args) throws InterruptedException {
		
		//阻塞队列
		ArrayBlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<Runnable>(2);
		//拒绝助手
		RejectedExecutionHandler handler = new RejectedExecutionHandler() {
			@Override
			public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
				System.out.println("线程池已满  ##### 任务被拒绝 ");
			}
		};
		//创建线程池
		ThreadPoolExecutor  pool =  new ThreadPoolExecutor(2, 4, 60L, TimeUnit.SECONDS, workQueue, handler);
										
		//1,2被核心线程处理
		pool.execute(new RunnableDemo(1,5000L));
		pool.execute(new RunnableDemo(2,5000L));
		Thread.sleep(100);
		//3,4放入阻塞队列,等核心线程或临时线程有空闲了再处理
		pool.execute(new RunnableDemo(3,2000L));
		pool.execute(new RunnableDemo(4,2000L));
		Thread.sleep(100);
		//5,6被临时线程处理
		pool.execute(new RunnableDemo(5,2000L));
		pool.execute(new RunnableDemo(6,2000L));
		Thread.sleep(100);
		//7,8被拒接助手处理了
		pool.execute(new RunnableDemo(7,2000L));
		pool.execute(new RunnableDemo(8,2000L));
		
		//线程池关闭
		pool.shutdown();
		
	}

}

class RunnableDemo implements Runnable {
	
	private int id;
	private long time;
	
	public RunnableDemo(int id, long time) {
		this.id = id;
		this.time = time;
	}
	
	@Override
	public void run() {
		try {
			
			System.out.println("id=" + id + " 开始执行!时间:" + System.currentTimeMillis());
			Thread.sleep(time);
			System.out.println("id=" + id + " 执行完成!时间:" + System.currentTimeMillis());
			
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
	}
	
}

二、ExecutorService 执行器服务

  • 获取线程池

通过Executors类的各个静态方法,可以直接获取常用配置的线程池。

例如:

ExecutorService executorService = Executors.newFixedThreadPool(5);

其实内部也是用ThreadPoolExecutor来实现:

public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }
  • 执行
execute(Runnable)没有返回结果
submit(Runnable)返回值类型为 Future,可以通过Future的get()方法来观察任务是否执行结束。若没结束,则该方法会阻塞。
submit(Callable)

与submit(Runnable)类似,唯一区别是submit(Callable)

还可以通过get() 方法获取返回结果。

invokeAny()入参为一个Callable或其子接口实例对象的集合,如果其中一个任务执行完成或者异常,其他的Callable将被取消。并返回其中一个Callable的执行结果。
invokeAll()入参为一个Callable或其子接口实例对象的集合,执行所有任务,并返回一个Future对象的集合。但是无法通过Future知道任务是正常结束还是执行异常。
  • 关闭线程池
shutdown()执行后则不再接受任务,直到任务执行完成才关闭
shutdownNow()立即关闭
  • 代码示例
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class ExecutorServiceDemo {
	
	public static void main(String[] args) throws Exception {
		ExecutorService executorService = Executors.newFixedThreadPool(5);
		Future<String> future = executorService.submit(new CallableDemo());
		
		//阻塞直到任务结束
		System.out.println(future.get());
		
		executorService.shutdown();
		
	}
}

class CallableDemo implements Callable<String> {

	public String call() throws Exception {
		System.out.println("开始执行!");
		Thread.sleep(3000);
		System.out.println("执行结束!");
		
		return "china@!";
	}
	
}

三、Lock锁

 

作用类似synchronized,但是更灵活,通过lock(),unlock()两个方法配合使用,保证线程安全。

lock()将 Lock 实例锁定
lockInterruptibly()lockInterruptibly() 方法将会被调用线程锁定,除非该线程被打断。此外,如果一个线程在通过这个方法来锁定 Lock 对象时进入阻塞等待,而它被打断了的话,该线程将会退出这个方法调用。
tryLock()试图立即锁定 Lock 实例。并返回成功结果,永不阻塞
unlock对 Lock 实例解锁
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class LockDemo {
	public static void main(String[] args) throws InterruptedException {
		Lock lock = new ReentrantLock();
		
		Thread t1 = new Thread(new T1(lock));
		Thread t3 = new Thread(new T1(lock));
			t1.start();
			Thread.sleep(100);
			t3.start();
			t3.interrupt();
		
	}
}

class T1 implements Runnable {
	
	Lock lock = null;
	
	public T1(Lock lock) {
		this.lock = lock;
	}
	public void run() {
		
		try {
			//当当前执行线程被打断时,当前线程会退出这个方法调用
			lock.lockInterruptibly();
			System.out.println("任务开始执行!");
			Thread.sleep(2000);
			System.out.println("任务执行结束!");
			
		} catch (Exception e) {
			System.out.println("线程被打断");
		}finally {
			lock.unlock();
		}
		
	}
	
}

四、ReadWriteLock读写锁

读是可以并发处理的,但是读和写,或者多个写是不可以并发处理的。

import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class ReadWriteLockDemo {
	
	public static String name = "lisi";
	public static void main(String[] args) {
		ReadWriteLock lock = new ReentrantReadWriteLock();
		//read可以并发
		new Thread(new TRead(lock)).start();
		new Thread(new TRead(lock)).start();
		new Thread(new TRead(lock)).start();
		//read+write 或者 多个write不能并发
		new Thread(new TWrite(lock)).start();
		new Thread(new TWrite(lock)).start();
		new Thread(new TRead(lock)).start();
		
	}
}

class TWrite implements Runnable {
	private ReadWriteLock lock = null;
	
	public TWrite(ReadWriteLock lock) {
		this.lock = lock;
	}
	
	public void run() {
		
		try {
			lock.writeLock().lock();
			System.out.println(Thread.currentThread().getId() + "  # 开始写数据");
			Thread.sleep(2000);
			ReadWriteLockDemo.name ="wangwu";
			System.out.println(Thread.currentThread().getId() + "  # 数据写入成功" + ReadWriteLockDemo.name);
			lock.writeLock().unlock();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
	}
}

class TRead implements Runnable {
	private ReadWriteLock lock = null;
	
	public TRead(ReadWriteLock lock) {
		this.lock = lock;
	}
	
	public void run() {
		
		try {
			lock.readLock().lock();
			System.out.println(Thread.currentThread().getId() + "  # 开始读数据");
			Thread.sleep(2000);
			ReadWriteLockDemo.name ="wangwu";
			System.out.println(Thread.currentThread().getId() + "  # 读取到数据" + ReadWriteLockDemo.name);
			lock.readLock().unlock();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
	}
}

 

数据治理是确保数据准确性、可靠性、安全性、可用性和完整性的体系和框架。它定义了组织内部如何使用、存储、保护和共享数据的规则和流程。数据治理的重要性随着数字化转型的加速而日益凸显,它能够提高决策效率、增强业务竞争力、降低风险,并促进业务创新。有效的数据治理体系可以确保数据在采集、存储、处理、共享和保护等环节的合规性和有效性。 数据质量管理是数据治理中的关键环节,它涉及数据质量评估、数据清洗、标准化和监控。高质量的数据能够提升业务决策的准确性,优化业务流程,并挖掘潜在的商业价值。随着大数据和人工智能技术的发展,数据质量管理在确保数据准确性和可靠性方面的作用愈发重要。企业需要建立完善的数据质量管理和校验机制,并通过数据清洗和标准化提高数据质量。 数据安全与隐私保护是数据治理中的另一个重要领域。随着数据量的快速增长和互联网技术的迅速发展,数据安全与隐私保护面临前所未有的挑战。企业需要加强数据安全与隐私保护的法律法规和技术手段,采用数据加密、脱敏和备份恢复等技术手段,以及加强培训和教育,提高安全意识和技能水平。 数据流程管理与监控是确保数据质量、提高数据利用率、保护数据安全的重要环节。有效的数据流程管理可以确保数据流程的合规性和高效性,而实时监控则有助于及时发现并解决潜在问题。企业需要设计合理的数据流程架构,制定详细的数据管理流程规范,并运用数据审计和可视化技术手段进行监控。 数据资产管理是将数据视为组织的重要资产,通过有效的管理和利用,为组织带来经济价值。数据资产管理涵盖数据的整个生命周期,包括数据的创建、存储、处理、共享、使用和保护。它面临的挑战包括数据量的快速增长、数据类型的多样化和数据更新的迅速性。组织需要建立完善的数据管理体系,提高数据处理和分析能力,以应对这些挑战。同时,数据资产的分类与评估、共享与使用规范也是数据资产管理的重要组成部分,需要制定合理的标准和规范,确保数据共享的安全性和隐私保护,以及建立合理的利益分配和权益保障机制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值