1. fastjson解析
解析json对象和数组,需要引入com.alibaba.fastjson 1.2.29版本。实例:
JSONArray jsonArray = JSONArray.parseArray("[\"abc\",\"def\"]");
List<String> fileNameList = jsonArray.toJavaList(String.class);
System.out.println(fileNameList); // [abc, def]
JSONObject jsonObject = JSONObject.parseObject("{\"a\" : \"b\", \"c\" : {\"d\" : true}}");
System.out.println(jsonObject.getString("a")); // b
System.out.println(jsonObject.getJSONObject("c").getBoolean("d")); // true
// 反序列化为泛型。
TypeReference<Set<String>> setTypeReference = new TypeReference<Set<String>>() {};
String data1 = "[3,2,1,1,1,1,1,2,7,3,3,5]";
System.out.println(JSONObject.parseObject(data1, setTypeReference)); // [3, 2, 1, 7, 5]
String data2 = "[\"3\",\"3\",\"3\",\"1\",\"1\",\"4\",\"4\"]";
System.out.println(JSONObject.parseObject(data2, setTypeReference)); // [3, 1, 4]
// 直接解析为Map<String, Object>,注意必须是json必须是object且符合json格式,否则会抛出异常。
String content = "{\"hello\" : 1,\"hello\":2}";
Map<String, Object> contentMap = JSONObject.parseObject(content);
System.out.println(contentMap); // {"hello":1,"world":2}
jar包依赖:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.29</version>
</dependency>
2. jackson解析
使用jackson解析,注意字符串中有model不存在的属性会抛出异常。fastjson不会。
ObjectMapper objectMapper = new ObjectMapper();
System.out.println(objectMapper.readValue("{\"a\":1}", RedirectXcdInfo.class));
mapper.writeValueAsString(obj)
jar依赖
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.8.7</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.7</version>
</dependency>
3. log4j配置
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.1.8</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.8</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.22</version>
</dependency>
<!-- logging end -->
4. 单例模式
private static class MemoizingConstructorSupplier {
final ConstructorSupplier delegate;
// 这里用volatile关键字,保证内存可见性
transient volatile boolean initialized;
transient Constructor value;
public MemoizingConstructorSupplier(ConstructorSupplier delegate) {
this.delegate = delegate;
}
public Constructor get() throws NoSuchMethodException, ClassNotFoundException {
if (!initialized) {
synchronized (this) {
if (!initialized) {
Constructor constructor = delegate.get();
value = constructor;
initialized = true;
return constructor;
}
}
}
return value;
}
}
5. 可重入锁ReentrantLock
/**
* Allocate a buffer of the given size. This method blocks if there is not enough memory and the buffer pool
* is configured with blocking mode.
*
* @param size The buffer size to allocate in bytes
* @param maxTimeToBlockMs The maximum time in milliseconds to block for buffer memory to be available
* @return The buffer
* @throws InterruptedException If the thread is interrupted while blocked
* @throws IllegalArgumentException if size is larger than the total memory controlled by the pool (and hence we would block
* forever)
*/
public ByteBuffer allocate(int size, long maxTimeToBlockMs) throws InterruptedException {
if (size > this.totalMemory)
throw new IllegalArgumentException("Attempt to allocate " + size
+ " bytes, but there is a hard limit of "
+ this.totalMemory
+ " on memory allocations.");
this.lock.lock();
try {
// check if we have a free buffer of the right size pooled
if (size == poolableSize && !this.free.isEmpty())
return this.free.pollFirst();
// now check if the request is immediately satisfiable with the
// memory on hand or if we need to block
int freeListSize = this.free.size() * this.poolableSize;
if (this.availableMemory + freeListSize >= size) {
// we have enough unallocated or pooled memory to immediately
// satisfy the request
freeUp(size);
this.availableMemory -= size;
lock.unlock();
return ByteBuffer.allocate(size);
} else {
// we are out of memory and will have to block
int accumulated = 0;
ByteBuffer buffer = null;
// 获取该锁的条件变量,一个锁可以有多个条件变量。
Condition moreMemory = this.lock.newCondition();
long remainingTimeToBlockNs = TimeUnit.MILLISECONDS.toNanos(maxTimeToBlockMs);
this.waiters.addLast(moreMemory);
// loop over and over until we have a buffer or have reserved
// enough memory to allocate one
while (accumulated < size) {
long startWaitNs = time.nanoseconds();
long timeNs;
boolean waitingTimeElapsed;
try {
// 进入等待,会释放锁,当往下执行时,会重新获得锁。
waitingTimeElapsed = !moreMemory.await(remainingTimeToBlockNs, TimeUnit.NANOSECONDS);
} catch (InterruptedException e) {
this.waiters.remove(moreMemory);
throw e;
} finally {
long endWaitNs = time.nanoseconds();
timeNs = Math.max(0L, endWaitNs - startWaitNs);
this.waitTime.record(timeNs, time.milliseconds());
}
if (waitingTimeElapsed) {
this.waiters.remove(moreMemory);
throw new TimeoutException("Failed to allocate memory within the configured max blocking time " + maxTimeToBlockMs + " ms.");
}
remainingTimeToBlockNs -= timeNs;
// check if we can satisfy this request from the free list,
// otherwise allocate memory
if (accumulated == 0 && size == this.poolableSize && !this.free.isEmpty()) {
// just grab a buffer from the free list
buffer = this.free.pollFirst();
accumulated = size;
} else {
// we'll need to allocate memory, but we may only get
// part of what we need on this iteration
freeUp(size - accumulated);
int got = (int) Math.min(size - accumulated, this.availableMemory);
this.availableMemory -= got;
accumulated += got;
}
}
// remove the condition for this thread to let the next thread
// in line start getting memory
Condition removed = this.waiters.removeFirst();
if (removed != moreMemory)
throw new IllegalStateException("Wrong condition: this shouldn't happen.");
// signal any additional waiters if there is more memory left
// over for them
if (this.availableMemory > 0 || !this.free.isEmpty()) {
if (!this.waiters.isEmpty())
// 唤醒该条件变量上的线程,注意ReentrantLock是公平锁,按照FIFO的原则处理条件变量,唤醒第一个线程。
this.waiters.peekFirst().signal();
}
// unlock and return the buffer
lock.unlock();
if (buffer == null)
return ByteBuffer.allocate(size);
else
return buffer;
}
} finally {
if (lock.isHeldByCurrentThread())
lock.unlock();
}
}
6. 线程安全的类
/*
* A threadsafe helper class to hold RecordBatches that haven't been ack'd yet
*/
private final static class IncompleteRecordBatches {
private final Set<RecordBatch> incomplete;
public IncompleteRecordBatches() {
this.incomplete = new HashSet<RecordBatch>();
}
// 这里都会产生阻塞,也可以用安全的HashSet
public void add(RecordBatch batch) {
synchronized (incomplete) {
this.incomplete.add(batch);
}
}
public void remove(RecordBatch batch) {
synchronized (incomplete) {
boolean removed = this.incomplete.remove(batch);
if (!removed)
throw new IllegalStateException("Remove from the incomplete set failed. This should be impossible.");
}
}
public Iterable<RecordBatch> all() {
synchronized (incomplete) {
return new ArrayList<RecordBatch>(this.incomplete);
}
}
}
7. 定时调度的线程(DomainUserServiceImpl)
private volatile Map<String, User> userMap = Collections.emptyMap();
private AtomicLong updateCnt = new AtomicLong(0);
@PostConstruct
private void init() {
updateMap();
scheduledThreadPool.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
updateMap();
}
}, 5, 5, TimeUnit.MINUTES);
}
private void updateMap() {
long cnt = updateCnt.getAndIncrement();
logger.info("updateMap start :{}", cnt);
try {
List<User> accounts = userDao.getAllUsers();
Map<String, User> userMapTemp = new HashMap<>(accounts.size(), 1F);
for (User user : accounts) {
userMapTemp.put(user.getUcAccount(), user);
}
this.userMap = userMapTemp;
logger.info("updateMap end :{}", cnt);
} catch (Exception e) {
QMonitor.recordOne("update local userMap schedule task exeption");
logger.info("updateMap exception :{}", cnt);
}
}
@Override
public boolean isGongdanUser(String ucAccount) {
return userMap.containsKey(ucAccount);
}
8. 线程池使用(ComplaintUpdateRemindDao)
private final ExecutorService executorService =
new ThreadPoolExecutor(6, 6,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(600),
new CustomThreadFactory());
public class CustomThreadFactory implements ThreadFactory, Thread.UncaughtExceptionHandler {
private final AtomicInteger threadNumber = new AtomicInteger(1);
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r, "pool_complaint_update_remind_" + threadNumber.getAndIncrement());
t.setUncaughtExceptionHandler(this);
return t;
}
public void uncaughtException(Thread thread, Throwable throwable) {
logger.error("Uncaught Exception in thread " + thread.getName(), throwable);
}
}
public void execute(final String orderNo, final ComplaintUpdateRemindType type) {
if (type == null) {
return;
}
executorService.execute(new Runnable() {
@Override
public void run() {
ComplaintUpdateRemind remind = new ComplaintUpdateRemind();
Complaint complaint = complaintDao.findComplaintByOrderNo(orderNo);
if (complaint == null) {
return;
}
if (complaint.getTaskStatus() == ComplaintStatus.FINISH.getCode() || complaint.getStep() == TaskStep.END || complaint.getTaskStatus() == ComplaintStatus.CANCLE
.getCode()) {
return;
}
if (StringUtils.isNotEmpty(complaint.getShouldProcessor()) && !SimpleConstants.SYSTEM.equals(complaint.getShouldProcessor())) {
remind.setMsgType(type.getCode());
remind.setUcAccount(complaint.getShouldProcessor());
remind.setOrderNo(orderNo);
remind.setIssueNo(complaint.getIssueNo());
zadd(remind);
}
}
});
}
9. tomcat插件配置
<build>
<finalName>websocketDemo</finalName>
<plugins>
<!-- Tomcat插件,使用jetty运行 -->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<port>8080</port>
<path>/</path>
<!-- 下面这行很关键,不然请求参数含有中文会出现乱码 -->
<uriEncoding>utf-8</uriEncoding>
</configuration>
</plugin>
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>${jetty.version}</version>
<configuration>
<webApp>
<contextPath>/</contextPath>
</webApp>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
10. 对于实际的tomcat,则需要在其配置文件conf/server.xml下添加
<Connector port="8080" protocol="HTTP/1.1"
maxThreads="200" connectionTimeout="20000"
enableLookups="false" compression="on"
redirectPort="8443"
URIEncoding="UTF-8"
compressableMimeType="text/csv,text/html,text/xml,text/css,text/plain,text/javascript,application/javascript,application/x-javascript,application/json,application/xml"
/>
11. java8 stream操作
- 片段1
EventTask eventTask1 = new EventTask();
eventTask1.setOperationDomain("a");
eventTask1.setEventType1(123);
EventTask eventTask2 = new EventTask();
eventTask2.setOperationDomain("a");
eventTask2.setEventType1(355);
List<EventTask> eventTaskList = Lists.newArrayList(eventTask1, eventTask2);
// 重复的域名,key,会出错
Map<String, EventTask> result1 = eventTaskList.stream().collect(
Collectors.toMap(EventTask::getOperationDomain, Function.identity()));
System.out.println(result1);
- 片段2
package com.jessin;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Random;
import static java.util.stream.Collectors.toList;
/**
* @author zexin.guo
* @create 2018-03-22 下午7:16
**/
public class TestStream {
private Logger logger = LoggerFactory.getLogger(getClass());
private static List<String> list = new ArrayList();
static {
Random random = new Random();
for (int i = 0; i < 5000000; i++) {
list.add(random.nextInt() > 0 ? "hello" : "world");
}
}
@Test
public void test1() {
long start = System.currentTimeMillis();
// list.stream将集合转化stream流
// filter是惰性求值
// count是及早求值统计
long count = list.stream().filter(a -> a.equals("hello")).count();
logger.info("count : {},耗时:{}ms", count, System.currentTimeMillis() - start);
start = System.currentTimeMillis();
count = 0;
for (String str : list) {
if ("hello".equals(str)) {
count++;
}
}
logger.info("count : {},耗时:{}ms", count, System.currentTimeMillis() - start);
}
@Test
public void test2() {
}
@Test
public void test3() {
List<String> list = new ArrayList();
list.add("hello");
list.add("abchelloorldd");
list.add("abc");
list.add("mbp");
List<String> filteredList = list.stream().filter(a -> a.contains("hello")).collect(toList());
logger.info("count : {}", filteredList);
}
@Test
public void test4() {
List<String> list = new ArrayList();
list.add("hello");
list.add("abchelloorldd");
list.add("hello");
list.add("world");
long count = list.stream().filter(a -> a.contains("hello")).distinct().count();
logger.info("count : {}", count);
}
@Test
public void test5() {
List<String> list = new ArrayList();
list.add("helalo");
list.add("abchelaloorldd");
list.add("hellworld");
list.add("worldhell");
List<String> resultList = list.stream().filter(a -> a.contains("hello")).distinct().limit(1).collect(toList());
logger.info("resultList : {}", resultList);
}
private class Entry {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Entry(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Entry{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
@Test
public void test6() {
List<Entry> list = new ArrayList();
list.add(new Entry("zexin.guo", 12));
list.add(new Entry("abc.def", 12));
// 从model中单独抽取一个值,将List<Entry>转化为List<String>
// collect转化为某种结果
List<String> resultList = list.stream().map(a -> a.getName()).collect(toList());
logger.info("count : {}", resultList);
}
@Test
public void test7() {
List<Entry> list = new ArrayList();
list.add(new Entry("zexin.guo", 12));
list.add(new Entry("abc.def", 13));
// 从model中单独抽取一个值,将List<Entry>转化为List<String>
// 返回Optional
Entry maxAgeEntry = list.stream().max(Comparator.comparing(a -> a.getAge())).get();
logger.info("count : {}", maxAgeEntry);
}
@Test
public void test8() {
List<Integer> list = new ArrayList();
list.add(1);
list.add(3);
list.add(2);
// sum是静态方法
// 规约
int sum = list.stream().reduce(0, Integer::sum);
logger.info("count : {}", sum);
}
}