CopyOnWriteArrayList集合
是一个线程安全的List集合,允许多个线程执行并发更新,但是只能有一个更新成功
双重校验锁机制:
package com.jt.common.thread;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Vector;
import java.util.concurrent.CopyOnWriteArrayList;
public class SyncTests {
//private static List<String> cache=new Vector<>();
//CopyOnWriteArrayList是一个线程安全的List集合,允许多个线程执行并发更新,但是只能有一个更新成功.
private static List<String> cache=new CopyOnWriteArrayList<>();//CAS(比较和交换)
// public synchronized static List<String> selectAll(){
// if (cache.isEmpty()) {
// System.out.println("Get Data From Database");
// List<String> data = Arrays.asList("A", "B", "C");
// cache.addAll(data);
// }
// return cache;
// }
public static List<String> selectAll(){
if(cache.isEmpty()) {//A,B,C,D
synchronized (cache) {
if (cache.isEmpty()) {
System.out.println("Get Data From Database");
List<String> data = Arrays.asList("A", "B", "C");
cache.addAll(data);
}
}
}
return cache;
}
public static void main(String[] args) {
//System.out.println(Thread.currentThread().getName());
Thread t1=new Thread(){
@Override
public void run() {
System.out.println(selectAll());
}
};
Thread t2=new Thread(){
@Override
public void run() {
System.out.println(selectAll());
}
};
Thread t3=new Thread(){
@Override
public void run() {
System.out.println(selectAll());
}
};
Thread t4=new Thread(){
@Override
public void run() {
System.out.println(selectAll());
}
};
Thread t5=new Thread(){
@Override
public void run() {
System.out.println(selectAll());
}
};
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
}
}
双层锁保证本地缓存安全
@RefreshScope
@RestController
public class ProviderCacheController {
@Value("${useLocalCache:false}")
private boolean useLocalCache;
@RequestMapping("/provider/cache01")
public String doUseLocalCache01() {
return "useLocalCache'value is " + useLocalCache;
}
//---------------------------------------------------------
//构建一个本地(Local)缓存对象(基于jvm中的一个对象存储从数据库获取的数据).
private List<String> cache = new ArrayList<>();
@RequestMapping("/provider/cache02")
public List<String> doUseLocalCache02() {
if (cache.isEmpty()) {
synchronized (cache) {
if (cache.isEmpty()) {//Thread-A,Thread-B,...
System.out.println("==Get data from database==");
//假设这部分分类信息是从数据库获取的,但是,我不希望每次获取分类信息都要从数据库查
List<String> cates = Arrays.asList("Category-A", "Category-B", "Category-C");
cache.addAll(cates);
}
}
}
return cache;
}//生产层面
}
共享nacos配置
server:
port: 8081
spring:
application:
name: sca-provider
cloud:
nacos:
discovery:
server-addr: localhost:8848
config:
server-addr: localhost:8848 #配置中心地址
file-extension: yml
namespace: 67d8daf6-d1a2-4796-a367-bd54bd58bc7a
group: DEFAULT_GROUP
shared-configs[0]: #共享配置
data-id: app-public.yml
refresh: true
测试配置
@RefreshScope
@RestController
public class ProviderSecretController {
@Value("${app.secret:123456}")
private String secret;
@GetMapping("/provider/secret")
public String doGetSecret(){
return "the secret is "+secret;
}
}
基于ScheduledExecutorService对象完成
一个多线程的任务调度,在nacos注册中心发送定时心跳
以及nacos配置中心数据定时拉取(pull),底层都是通过
这个对象完成的.
public class ScheduledExecutorServiceUtils {
public static void main(String[] args) {
//......
ScheduledExecutorService ses = Executors.newScheduledThreadPool(3);
Runnable task=new Runnable() {
@Override
public void run() {
String tName = Thread.currentThread().getName();
System.out.println(tName+"->"+System.currentTimeMillis());
}
};
ses.scheduleAtFixedRate(task,
1,
1,
TimeUnit.SECONDS);
}
}