扩展知识1:读写锁**
ReadWriteLock接口:可以实现多个读线程同时读取数据,写线程需要互斥执行。
读|写 、写|写 需要互斥
读|读 不需要互斥
示例:创建资源类`
public class Res {
private int num;
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
}
测试类:
import java.util.Random;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class Demo1 {
public static void main(String[] args) {
// 共享资源
Res res=new Res();
// 创建读写锁
ReentrantReadWriteLock lock=new ReentrantReadWriteLock();
//写入
Runnable runnable=new Runnable() {
@Override
public void run() {
//上锁
lock.writeLock().lock();
try {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
int n= new Random().nextInt(1000);
res.setNum(n);
System.out.println(Thread.currentThread().getName()+"写入"+n);
} finally {
//解锁
lock.writeLock().unlock();
}
}
};
//读取
Runnable runnable1=new Runnable() {
@Override
public void run() {
//上锁
lock.readLock().lock();
try {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
int num=res.getNum();
System.out.println(Thread.currentThread().getName()+"读取"+num);
} finally {
lock.readLock().unlock();
}
}
};
//创建线程
for (int i = 0; i < 10; i++) {
new Thread(runnable).start();
}
for (int i = 0; i < 10; i++) {
new Thread(runnable1).start();
}
}
}
扩展知识2:线程池
为什么需要线程池:
例如有非常的多的任务需要多线程来完成,且每个线程执行时间不会太长,这样会频繁的创建和销毁线程。频繁创建和销毁线程会比较耗性能。如果有了线程池就不要创建更多的线程来完成任务,因为线程可以重用。
线程池用维护者一个队列,队列中保存着处于等待(空闲)状态的线程。不用每次都创建新的线程。和线程池相关的接口和类存在java.util.concurrent并发包中。
接口:
1、 Executor:线程池的核心接口,负责线程的创建使用和调度的根接口
2 、ExecutorService: Executor的子接口,线程池的主要接口, 提供基本功能。
3 、ScheduledExecutorService: ExecutorService的子接口,负责线程调度的子接口。
实现类:
1、 ThreadPoolExecutor:ExecutorService的实现类,负责线程池的创建使用。
2 、ScheduledThreadPoolExecutor:继承 ThreadPoolExecutor,并实现 ScheduledExecutorService接口,既有线程池的功能,又具有线程调度功能。
3 、Executors:线程池的工具类,负责线程池的创建。
newFixedThreadPool();创建固定大小的线程池。
newCachedThreadPool();创建缓存线程池,线程池大小没有限制。根据需求自动调整线程数量。
newSingleThreadExecutor();创建单个线程的线程池,只有一个线程。
newScheduledThreadPool();创建固定大小的线程池,可以延迟或定时执行任务。
示例:
public class Ticket implements Runnable {
private int ticket=1000;
private Lock lock=new ReentrantLock();
@Override
public void run() {
while (true){
//上锁
lock.lock();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
if(ticket<1){
break;
}
System.out.println(Thread.currentThread().getName()+"卖了第"+ticket+"张票");
ticket--;
} finally {
lock.unlock(); //解锁
}
}
}
}
测试类:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Demo1 {
public static void main(String[] args) {
//创建票对象
Ticket ticket=new Ticket();
//创建线程池(4个线程)
ExecutorService executorService = Executors.newFixedThreadPool(4);
//分配任务
for (int i = 0; i < 4; i++) {
executorService.submit(ticket);
}
//关闭
executorService.shutdown();
}
}
扩展知识3:定时器Timer
public class Demo6 {
public static void main(String[] args) {
//1创建Timer对象
Timer timer=new Timer();
//2创建任务
TimerTask timerTask=new TimerTask() {
int index=0;
@Override
public void run() {
for(int i=0;i<10;i++){
System.out.println(Thread.currentThread().getName()+"===="+i);
}
//取消
//timer.cancel();
System.out.println("------------------------------------");
index++;
if(index==10){
timer.cancel();
}
}
};
//3分配任务
//timer.schedule(timerTask,3000);
timer.schedule(timerTask, 0, 2000);
// //4取消
// timer.cancel();
}
}