自定义注解标记属性
- 用于标记【线程安全】注解类。
package com.mmall.annoations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 自定义注解,用于标记【线程安全】注解类。
* Created by megan on 2018/3/18.
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface ThreadSafe {
String value() default "";
}
- 用于标记【线程不安全】注解类。
package com.mmall.annoations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 自定义注解,用于标记【线程不安全】注解类。
* Created by megan on 2018/3/18.
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface NotThreadSafe {
String value() default "";
}
- 用于标记【推荐】注解类。
package com.mmall.annoations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 自定义注解,用于标记【推荐】注解类。
* Created by megan on 2018/3/18.
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface Recommend {
String value() default "";
}
- 用于标记【不推荐】注解类。
package com.mmall.annoations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 自定义注解,用于标记【不推荐】注解类。
* Created by megan on 2018/3/18.
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface NotRecommend {
String value() default "";
}
- ElementType 详解
public enum ElementType {
/** 声明注解作用在类,借口,枚举上 */
TYPE,
/** 声明注解作用在属性上 */
FIELD,
/** 声明注解作用在方法上 */
METHOD,
/** 声明注解作用在参数上 */
PARAMETER,
/** 声明注解作用在构造函数上 */
CONSTRUCTOR,
/** 声明注解作用在本地变量上 */
LOCAL_VARIABLE,
/** 声明注解作用在注解上 */
ANNOTATION_TYPE,
/** 声明注解作用在包上 */
PACKAGE,
/**
* 声明注解可以应用在TYPE声明上
* @since 1.8
*/
TYPE_PARAMETER,
/**
* 表示这个 Annotation 可以用在所有使用 Type 的地方(如:泛型,类型转换等)
* @since 1.8
*/
TYPE_USE
}
- RetentionPolicy详解
public enum RetentionPolicy {
/**
* 在编译的时候会被取消,只用于声明,理解,或者测试
*/
SOURCE,
/**
* 注解将被编译器记录在类文件中,但在运行时不需要由VM保留,(默认的选项)
*/
CLASS,
/**
* 注解将被编译器记录在类文件中,但在运行时由VM保留,这样他们可以被反射获取(当你需要获取注解中字段的属性值的时候,需要用这个,比如AOP)
* @see java.lang.reflect.AnnotatedElement
*/
RUNTIME
}
并发模拟工具
-
Postman : http请求模拟工具
postman
-
Apache Bench (AB)
AB
# -n 总请求数
# -c 并发数
$ ab -n 1000 -c 50 http://localhost:8080/test
This is ApacheBench, Version 2.3 <$Revision: 1807734 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking localhost (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests
Server Software:
Server Hostname: localhost
Server Port: 8080
Document Path: /test
Document Length: 4 bytes
# 并发量
Concurrency Level: 50
# 整个测试耗时
Time taken for tests: 0.633 seconds
# 完成的请求数
Complete requests: 1000
# 失败的请求数
Failed requests: 0
# 所有请求的相应数据的长度综合(HTTP相应数据的 头信息+正文数据的长度)(不包括请求的长度)
Total transferred: 136000 bytes
# 所有请求的相应数据中,正文相应的综合
HTML transferred: 4000 bytes
# 吞吐率(与并发数相关)(Complete requests/0.285 seconds)
Requests per second: 1580.45 [#/sec] (mean)
# 用户平均请求等待时间
Time per request: 31.637 [ms] (mean)
# 服务器平均请求等待时间
Time per request: 0.633 [ms] (mean, across all concurrent requests)
# 这些请求在单位时间内从服务器获取的数据长度(Total transferred/Time taken for tests)
Transfer rate: 209.90 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 11 5.9 11 41
Processing: 1 20 11.8 17 71
Waiting: 0 14 9.9 13 60
Total: 9 31 11.0 28 76
Percentage of the requests served within a certain time (ms)
50% 28
66% 31
75% 34
80% 37
90% 41
95% 55
98% 71
99% 72
100% 76 (longest request)
-
JMeter
JMeter
代码模拟并发:
-
CountDownLatch
CountDownLatch
-
Semaphore
Semaphore
package com.mmall.test;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.*;
/**
* 模拟并发测试代码(线程不安全的)
* Created by megan on 2018/3/18.
*/
@Slf4j
@NotThreadSafe
public class ConcurrencyTest {
/** 请求数 **/
public static int clientTotal = 5000;
/** 同时并发执行线程数 **/
public static int threadTotal = 200;
/** 计数器 **/
public static int count = 0;
public static void main(String[] args) throws Exception{
//定义一个线程池
ExecutorService executorService = Executors.newCachedThreadPool();
// 信号量,闭锁
final Semaphore semaphore = new Semaphore(threadTotal);
final CountDownLatch countDownLatch = new CountDownLatch(clientTotal);
// 模拟并发请求
for(int i = 0; i < clientTotal; i ++){
executorService.execute(() -> {
try {
// 请求一个信号,如果信号量小于clientTotal,则阻塞
semaphore.acquire();
add();
// 释放一个信号
semaphore.release();
} catch (InterruptedException e) {
log.error("exception",e);
}
countDownLatch.countDown();
});
}
// 阻塞直到countDown 的次数为threadTotal
countDownLatch.await();
// 关闭线程池
executorService.shutdown();
log.info("count:{}",count);
}
/**
* 本质上应该是这个方法线程不安全
*/
private static void add(){
count++;
}
}
网友评论