一、application-dev.yml
spring:
#redis
redis:
host: 127.0.0.1
port: 6379
lettuce:
pool:
#连接池最大连接数(负值表示没有限制)
max-active: -1
#最大阻塞时间,单位ms
max-wait: 2000
#最大空闲连接数
max-idle: 100
#最小空闲连接数
min-idle: 0
#连接超时时间,单位ms
timeout: 2000
二、RedisConfig
1 package com.miaoshaproject.config; 2 3 import com.fasterxml.jackson.annotation.JsonAutoDetect; 4 import com.fasterxml.jackson.annotation.PropertyAccessor; 5 import com.fasterxml.jackson.databind.ObjectMapper; 6 import org.springframework.context.annotation.Bean; 7 import org.springframework.context.annotation.Configuration; 8 import org.springframework.data.redis.connection.RedisConnectionFactory; 9 import org.springframework.data.redis.core.RedisTemplate; 10 import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; 11 import org.springframework.data.redis.serializer.StringRedisSerializer; 12 13 /* 14 @Author wangshuo 15 @Date 2022/5/15, 9:42 16 Please add a comment 17 */ 18 @Configuration 19 public class RedisConfig { 20 21 @Bean 22 @SuppressWarnings("all") 23 public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) { 24 25 RedisTemplate<String, Object> template = new RedisTemplate<String, Object>(); 26 template.setConnectionFactory(factory); 27 Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); 28 ObjectMapper om = new ObjectMapper(); 29 om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); 30 om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); 31 jackson2JsonRedisSerializer.setObjectMapper(om); 32 StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); 33 // key采用String的序列化方式 34 template.setKeySerializer(stringRedisSerializer); 35 36 // hash的key也采用String的序列化方式 37 template.setHashKeySerializer(stringRedisSerializer); 38 39 // value序列化方式采用jackson 40 template.setValueSerializer(jackson2JsonRedisSerializer); 41 42 // hash的value序列化方式采用jackson 43 template.setHashValueSerializer(jackson2JsonRedisSerializer); 44 45 template.afterPropertiesSet(); 46 return template; 47 } 48 }
三、RedisUtil
1 package com.miaoshaproject.util.redis; 2 3 import lombok.extern.slf4j.Slf4j; 4 import org.springframework.beans.factory.annotation.Autowired; 5 import org.springframework.data.redis.core.RedisTemplate; 6 import org.springframework.stereotype.Component; 7 import org.springframework.util.CollectionUtils; 8 9 import java.util.*; 10 import java.util.concurrent.TimeUnit; 11 12 /** 13 * @Author wangshuo 14 * @Date 2022/5/15, 15:30 15 * Please add a comment 16 */ 17 18 @Component 19 @Slf4j 20 public class RedisUtil { 21 @Autowired 22 public RedisTemplate<String, Object> redisTemplate; 23 24 // =============================1-common============================ 25 26 /** 27 * 指定缓存失效时间 28 * 29 * @param key 键 30 * @param time 时间(秒) 31 * @return 32 */ 33 public boolean expire(String key, long time) { 34 try { 35 if (time > 0) { 36 redisTemplate.expire(key, time, TimeUnit.SECONDS); 37 } 38 return true; 39 } catch (Exception e) { 40 log.error(key, e); 41 return false; 42 } 43 } 44 45 /** 46 * 根据key 获取过期时间 47 * 48 * @param key 键 不能为null 49 * @return 时间(秒) 返回0代表为永久有效 50 */ 51 public long getExpire(String key) { 52 return redisTemplate.getExpire(key, TimeUnit.SECONDS); 53 } 54 55 /** 56 * 判断key是否存在 57 * 58 * @param key 键 59 * @return true 存在 false不存在 60 */ 61 public boolean hasKey(String key) { 62 try { 63 return redisTemplate.hasKey(key); 64 } catch (Exception e) { 65 log.error(key, e); 66 return false; 67 } 68 } 69 70 /** 71 * 删除缓存 72 * 73 * @param key 可以传一个值 或多个 74 */ 75 @SuppressWarnings("unchecked") 76 public void del(String... key) { 77 if (key != null && key.length > 0) { 78 if (key.length == 1) { 79 redisTemplate.delete(key[0]); 80 } else { 81 redisTemplate.delete((Collection<String>) CollectionUtils.arrayToList(key)); 82 } 83 } 84 } 85 86 // ============================2-String============================= 87 88 /** 89 * 普通缓存获取 90 * 91 * @param key 键 92 * @return 值 93 */ 94 public Object get(String key) { 95 return key == null ? null : redisTemplate.opsForValue().get(key); 96 } 97 98 /** 99 * 普通缓存放入 100 * 101 * @param key 键 102 * @param value 值 103 * @return true成功 false失败 104 */ 105 public boolean set(String key, Object value) { 106 try { 107 redisTemplate.opsForValue().set(key, value); 108 return true; 109 } catch (Exception e) { 110 log.error(key, e); 111 return false; 112 } 113 114 } 115 116 /** 117 * 插入数据,若数据已存在,返回false 118 * 119 * @param key 键 120 * @param value 值 121 * @return true成功 false失败 122 */ 123 public boolean setnx(String key, Object value) { 124 try { 125 Boolean aBoolean = redisTemplate.opsForValue().setIfAbsent(key, value); 126 if (aBoolean) 127 return true; 128 else 129 return false; 130 } catch (Exception e) { 131 log.error(key, e); 132 return false; 133 } 134 } 135 136 /** 137 * 插入数据,若数据已存在,返回false 设置过期时间 138 * 139 * @param key 键 140 * @param value 值 141 * @return true成功 false失败 142 */ 143 public boolean setnx(String key, Object value, long time) { 144 try { 145 Boolean aBoolean = redisTemplate.opsForValue().setIfAbsent(key, value, time, TimeUnit.SECONDS); 146 if (aBoolean) 147 return true; 148 else 149 return false; 150 } catch (Exception e) { 151 log.error(key, e); 152 return false; 153 } 154 } 155 156 /** 157 * 普通缓存放入并设置时间 158 * 159 * @param key 键 160 * @param value 值 161 * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期 162 * @return true成功 false 失败 163 */ 164 public boolean set(String key, Object value, long time) { 165 try { 166 if (time > 0) { 167 redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS); 168 } else { 169 set(key, value); 170 } 171 return true; 172 } catch (Exception e) { 173 log.error(key, e); 174 return false; 175 } 176 } 177 178 /** 179 * 递增 适用场景: https://blog.csdn.net/y_y_y_k_k_k_k/article/details/79218254 高并发生成订单号,秒杀类的业务逻辑等。。 180 * 181 * @param key 键 182 * @param delta 要增加几(大于0) 183 * @return 184 */ 185 public long incr(String key, long delta) { 186 if (delta < 0) { 187 throw new RuntimeException("递增因子必须大于0"); 188 } 189 return redisTemplate.opsForValue().increment(key, delta); 190 } 191 192 /** 193 * 递减 194 * 195 * @param key 键 196 * @param delta 要减少几(小于0) 197 * @return 198 */ 199 public long decr(String key, long delta) { 200 if (delta < 0) { 201 throw new RuntimeException("递减因子必须大于0"); 202 } 203 return redisTemplate.opsForValue().increment(key, -delta); 204 } 205 206 // ================================3-Map================================= 207 208 /** 209 * HashGet 210 * 211 * @param key 键 不能为null 212 * @param item 项 不能为null 213 * @return 值 214 */ 215 public Object hget(String key, String item) { 216 return redisTemplate.opsForHash().get(key, item); 217 } 218 219 /** 220 * 获取hashKey对应的所有键值 221 * 222 * @param key 键 223 * @return 对应的多个键值 224 */ 225 public Map<Object, Object> hmget(String key) { 226 return redisTemplate.opsForHash().entries(key); 227 } 228 229 /** 230 * HashSet 231 * 232 * @param key 键 233 * @param map 对应多个键值 234 * @return true 成功 false 失败 235 */ 236 public boolean hmset(String key, Map<String, Object> map) { 237 try { 238 redisTemplate.opsForHash().putAll(key, map); 239 return true; 240 } catch (Exception e) { 241 log.error(key, e); 242 return false; 243 } 244 } 245 246 /** 247 * HashSet 并设置时间 248 * 249 * @param key 键 250 * @param map 对应多个键值 251 * @param time 时间(秒) 252 * @return true成功 false失败 253 */ 254 public boolean hmset(String key, Map<String, Object> map, long time) { 255 try { 256 redisTemplate.opsForHash().putAll(key, map); 257 if (time > 0) { 258 expire(key, time); 259 } 260 return true; 261 } catch (Exception e) { 262 log.error(key, e); 263 return false; 264 } 265 } 266 267 /** 268 * 向一张hash表中放入数据,如果不存在将创建 269 * 270 * @param key 键 271 * @param item 项 272 * @param value 值 273 * @return true 成功 false失败 274 */ 275 public boolean hset(String key, String item, Object value) { 276 try { 277 redisTemplate.opsForHash().put(key, item, value); 278 return true; 279 } catch (Exception e) { 280 log.error(key, e); 281 return false; 282 } 283 } 284 285 /** 286 * 向一张hash表中放入数据,如果不存在将创建 287 * 288 * @param key 键 289 * @param item 项 290 * @param value 值 291 * @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间 292 * @return true 成功 false失败 293 */ 294 public boolean hset(String key, String item, Object value, long time) { 295 try { 296 redisTemplate.opsForHash().put(key, item, value); 297 if (time > 0) { 298 expire(key, time); 299 } 300 return true; 301 } catch (Exception e) { 302 log.error(key, e); 303 return false; 304 } 305 } 306 307 /** 308 * 删除hash表中的值 309 * 310 * @param key 键 不能为null 311 * @param item 项 可以使多个 不能为null 312 */ 313 public void hdel(String key, Object... item) { 314 redisTemplate.opsForHash().delete(key, item); 315 } 316 317 /** 318 * 判断hash表中是否有该项的值 319 * 320 * @param key 键 不能为null 321 * @param item 项 不能为null 322 * @return true 存在 false不存在 323 */ 324 public boolean hHasKey(String key, String item) { 325 return redisTemplate.opsForHash().hasKey(key, item); 326 } 327 328 /** 329 * hash递增 如果不存在,就会创建一个 并把新增后的值返回 330 * 331 * @param key 键 332 * @param item 项 333 * @param by 要增加几(大于0) 334 * @return 335 */ 336 public double hincr(String key, String item, double by) { 337 return redisTemplate.opsForHash().increment(key, item, by); 338 } 339 340 /** 341 * hash递减 342 * 343 * @param key 键 344 * @param item 项 345 * @param by 要减少记(小于0) 346 * @return 347 */ 348 public double hdecr(String key, String item, double by) { 349 return redisTemplate.opsForHash().increment(key, item, -by); 350 } 351 352 // ============================4-set============================= 353 354 /** 355 * 根据key获取Set中的所有值 356 * 357 * @param key 键 358 * @return 359 */ 360 public Set<Object> sGet(String key) { 361 try { 362 return redisTemplate.opsForSet().members(key); 363 } catch (Exception e) { 364 log.error(key, e); 365 return null; 366 } 367 } 368 369 /** 370 * 根据value从一个set中查询,是否存在 371 * 372 * @param key 键 373 * @param value 值 374 * @return true 存在 false不存在 375 */ 376 public boolean sHasKey(String key, Object value) { 377 try { 378 return redisTemplate.opsForSet().isMember(key, value); 379 } catch (Exception e) { 380 log.error(key, e); 381 return false; 382 } 383 } 384 385 /** 386 * 将数据放入set缓存 387 * 388 * @param key 键 389 * @param values 值 可以是多个 390 * @return 成功个数 391 */ 392 public long sSet(String key, Object... values) { 393 try { 394 return redisTemplate.opsForSet().add(key, values); 395 } catch (Exception e) { 396 log.error(key, e); 397 return 0; 398 } 399 } 400 401 /** 402 * 将set数据放入缓存 403 * 404 * @param key 键 405 * @param time 时间(秒) 406 * @param values 值 可以是多个 407 * @return 成功个数 408 */ 409 public long sSetAndTime(String key, long time, Object... values) { 410 try { 411 Long count = redisTemplate.opsForSet().add(key, values); 412 if (time > 0) 413 expire(key, time); 414 return count; 415 } catch (Exception e) { 416 log.error(key, e); 417 return 0; 418 } 419 } 420 421 /** 422 * 获取set缓存的长度 423 * 424 * @param key 键 425 * @return 426 */ 427 public long sGetSetSize(String key) { 428 try { 429 return redisTemplate.opsForSet().size(key); 430 } catch (Exception e) { 431 log.error(key, e); 432 return 0; 433 } 434 } 435 436 /** 437 * 移除值为value的 438 * 439 * @param key 键 440 * @param values 值 可以是多个 441 * @return 移除的个数 442 */ 443 public long setRemove(String key, Object... values) { 444 try { 445 Long count = redisTemplate.opsForSet().remove(key, values); 446 return count; 447 } catch (Exception e) { 448 log.error(key, e); 449 return 0; 450 } 451 } 452 453 // ============================5-zset============================= 454 455 /** 456 * 根据key获取Set中的所有值 457 * 458 * @param key 键 459 * @return 460 */ 461 public Set<Object> zSGet(String key) { 462 try { 463 return redisTemplate.opsForSet().members(key); 464 } catch (Exception e) { 465 log.error(key, e); 466 return null; 467 } 468 } 469 470 /** 471 * 根据value从一个set中查询,是否存在 472 * 473 * @param key 键 474 * @param value 值 475 * @return true 存在 false不存在 476 */ 477 public boolean zSHasKey(String key, Object value) { 478 try { 479 return redisTemplate.opsForSet().isMember(key, value); 480 } catch (Exception e) { 481 log.error(key, e); 482 return false; 483 } 484 } 485 486 public Boolean zSSet(String key, Object value, double score) { 487 try { 488 return redisTemplate.opsForZSet().add(key, value, 2); 489 } catch (Exception e) { 490 log.error(key, e); 491 return false; 492 } 493 } 494 495 /** 496 * 将set数据放入缓存 497 * 498 * @param key 键 499 * @param time 时间(秒) 500 * @param values 值 可以是多个 501 * @return 成功个数 502 */ 503 public long zSSetAndTime(String key, long time, Object... values) { 504 try { 505 Long count = redisTemplate.opsForSet().add(key, values); 506 if (time > 0) 507 expire(key, time); 508 return count; 509 } catch (Exception e) { 510 log.error(key, e); 511 return 0; 512 } 513 } 514 515 /** 516 * 获取set缓存的长度 517 * 518 * @param key 键 519 * @return 520 */ 521 public long zSGetSetSize(String key) { 522 try { 523 return redisTemplate.opsForSet().size(key); 524 } catch (Exception e) { 525 log.error(key, e); 526 return 0; 527 } 528 } 529 530 /** 531 * 移除值为value的 532 * 533 * @param key 键 534 * @param values 值 可以是多个 535 * @return 移除的个数 536 */ 537 public long zSetRemove(String key, Object... values) { 538 try { 539 Long count = redisTemplate.opsForSet().remove(key, values); 540 return count; 541 } catch (Exception e) { 542 log.error(key, e); 543 return 0; 544 } 545 } 546 // ===============================6-list================================= 547 548 /** 549 * 获取list缓存的内容 550 * 551 * @param key 键 552 * @param start 开始 0 是第一个元素 553 * @param end 结束 -1代表所有值 554 * @return 555 * @取出来的元素 总数 end-start+1 556 */ 557 public List<Object> lGet(String key, long start, long end) { 558 try { 559 return redisTemplate.opsForList().range(key, start, end); 560 } catch (Exception e) { 561 log.error(key, e); 562 return null; 563 } 564 } 565 566 /** 567 * 获取list缓存的长度 568 * 569 * @param key 键 570 * @return 571 */ 572 public long lGetListSize(String key) { 573 try { 574 return redisTemplate.opsForList().size(key); 575 } catch (Exception e) { 576 log.error(key, e); 577 return 0; 578 } 579 } 580 581 /** 582 * 通过索引 获取list中的值 583 * 584 * @param key 键 585 * @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推 586 * @return 587 */ 588 public Object lGetIndex(String key, long index) { 589 try { 590 return redisTemplate.opsForList().index(key, index); 591 } catch (Exception e) { 592 log.error(key, e); 593 return null; 594 } 595 } 596 597 /** 598 * 将list放入缓存 599 * 600 * @param key 键 601 * @param value 值 602 * @return 603 */ 604 public boolean lSet(String key, Object value) { 605 try { 606 redisTemplate.opsForList().rightPush(key, value); 607 return true; 608 } catch (Exception e) { 609 log.error(key, e); 610 return false; 611 } 612 } 613 614 /** 615 * 将list放入缓存 616 * 617 * @param key 键 618 * @param value 值 619 * @param time 时间(秒) 620 * @return 621 */ 622 public boolean lSet(String key, Object value, long time) { 623 try { 624 redisTemplate.opsForList().rightPush(key, value); 625 if (time > 0) 626 expire(key, time); 627 return true; 628 } catch (Exception e) { 629 log.error(key, e); 630 return false; 631 } 632 } 633 634 /** 635 * 将list放入缓存 636 * 637 * @param key 键 638 * @param value 值 639 * @return 640 */ 641 public boolean lSet(String key, List<Object> value) { 642 try { 643 redisTemplate.opsForList().rightPushAll(key, value); 644 return true; 645 } catch (Exception e) { 646 log.error(key, e); 647 return false; 648 } 649 } 650 651 /** 652 * 将list放入缓存 653 * 654 * @param key 键 655 * @param value 值 656 * @param time 时间(秒) 657 * @return 658 */ 659 public boolean lSet(String key, List<Object> value, long time) { 660 try { 661 redisTemplate.opsForList().rightPushAll(key, value); 662 if (time > 0) 663 expire(key, time); 664 return true; 665 } catch (Exception e) { 666 log.error(key, e); 667 return false; 668 } 669 } 670 671 /** 672 * 根据索引修改list中的某条数据 673 * 674 * @param key 键 675 * @param index 索引 676 * @param value 值 677 * @return 678 */ 679 public boolean lUpdateIndex(String key, long index, Object value) { 680 try { 681 redisTemplate.opsForList().set(key, index, value); 682 return true; 683 } catch (Exception e) { 684 log.error(key, e); 685 return false; 686 } 687 } 688 689 /** 690 * 移除N个值为value 691 * 692 * @param key 键 693 * @param count 移除多少个 694 * @param value 值 695 * @return 移除的个数 696 */ 697 public long lRemove(String key, long count, Object value) { 698 try { 699 Long remove = redisTemplate.opsForList().remove(key, count, value); 700 return remove; 701 } catch (Exception e) { 702 log.error(key, e); 703 return 0; 704 } 705 } 706 }
四、RedisUtilTest
1 package com.miaoshaproject; 2 3 import java.io.Serializable; 4 import java.util.Date; 5 import java.util.List; 6 import java.util.Map; 7 import java.util.Map.Entry; 8 import java.util.concurrent.LinkedBlockingQueue; 9 import java.util.concurrent.ThreadPoolExecutor; 10 import java.util.concurrent.TimeUnit; 11 12 import com.miaoshaproject.util.redis.RedisUtil; 13 import org.apache.commons.lang3.StringUtils; 14 import org.junit.AfterClass; 15 import org.junit.Assert; 16 import org.junit.BeforeClass; 17 import org.junit.Ignore; 18 import org.junit.Test; 19 import org.junit.runner.RunWith; 20 import org.springframework.beans.factory.annotation.Autowired; 21 import org.springframework.boot.test.context.SpringBootTest; 22 import org.springframework.test.context.junit4.SpringRunner; 23 24 import lombok.Data; 25 26 /** 27 * @Author wangshuo 28 * @Date 2022/5/15, 15:34 29 * Please add a comment 30 */ 31 32 @RunWith(SpringRunner.class) 33 @SpringBootTest 34 public class RedisUtilTest { 35 @Autowired 36 private RedisUtil redisUtil; 37 38 @BeforeClass 39 public static void setUpBeforeClass() throws Exception { 40 } 41 42 @AfterClass 43 public static void tearDownAfterClass() throws Exception { 44 } 45 46 /** 47 * 设置缓存过期时间 48 * 49 */ 50 @Test 51 public void testExpire() throws Exception { 52 redisUtil.set("aaaKey", "aaaValue"); 53 redisUtil.expire("aaaKey", 100); 54 Assert.assertEquals(redisUtil.get("aaaKey"), "aaaValue"); 55 TimeUnit.SECONDS.sleep(100); 56 Assert.assertNotEquals(redisUtil.get("aaaKey"), "aaaValue"); 57 58 } 59 60 @Test 61 public void testGetExpire() throws Exception { 62 redisUtil.set("aaaKey", "aaaValue"); 63 redisUtil.expire("aaaKey", 100); 64 // 设置了缓存就会及时的生效,所以缓存时间小于最初设置的时间 65 Assert.assertTrue(redisUtil.getExpire("aaaKey") < 100L); 66 } 67 68 @Test 69 public void testHasKey() throws Exception { 70 redisUtil.set("aaaKey", "aaaValue"); 71 // 存在的 72 Assert.assertTrue(redisUtil.hasKey("aaaKey")); 73 // 不存在的 74 Assert.assertFalse(redisUtil.hasKey("bbbKey")); 75 } 76 77 @Test 78 public void testDel() throws Exception { 79 redisUtil.set("aaaKey", "aaaValue"); 80 // 存在的 81 Assert.assertTrue(redisUtil.hasKey("aaaKey")); 82 redisUtil.del("aaaKey"); 83 Assert.assertFalse(redisUtil.hasKey("bbbKey")); 84 } 85 86 @Test 87 public void testGet() throws Exception { 88 redisUtil.set("aaaKey", "aaaValue"); 89 Assert.assertEquals(redisUtil.get("aaaKey"), "aaaValue"); 90 } 91 92 @Test 93 public void testSetStringObject() throws Exception { 94 Assert.assertTrue(redisUtil.set("aaaKey", "aaaValue")); 95 } 96 97 @Test 98 public void testSetStringObjectLong() throws Exception { 99 Assert.assertTrue(redisUtil.set("aaaKeyLong", 100L)); 100 } 101 102 @Test 103 public void testSetObject() { 104 // 测试对象 105 TestModel testModel = new TestModel(); 106 testModel.setId(System.currentTimeMillis()); 107 testModel.setName("测试"); 108 redisUtil.set("testModel", testModel); 109 TestModel testModel2 = (TestModel) redisUtil.get("testModel"); 110 System.err.println(testModel2); 111 System.err.println(testModel2.getName()); 112 System.err.println(testModel2.getId()); 113 } 114 115 @Test 116 @Ignore 117 public void testIncr() throws Exception { 118 String key = "testIncr"; 119 redisUtil.incr(key, 1); 120 redisUtil.expire(key, 10); // 缓存失效10s 121 Assert.assertEquals(redisUtil.get(key), 1); 122 } 123 124 // 高并发下 递增 测试 125 @Test 126 @Ignore 127 public void testIncr2() throws Exception { 128 // 模拟发送短信的并发 129 // 首先开启一个线程池,创建一个专门消费短信的线程 130 // 一次性放入多个线程实例 ,实例 都是2秒请求一次 ,而10s内的只能允许一条。 也就是说我测试100个线程,只能10s一条 131 ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(6, 6, 30, TimeUnit.SECONDS, new LinkedBlockingQueue<>(100)); 132 Thread[] threads = new Thread[100]; 133 for (int i = 0; i < 100; i++) { 134 threads[i] = new Thread(new Runnable() { 135 @Override 136 public void run() { 137 try { 138 TimeUnit.SECONDS.sleep(2); 139 } catch (InterruptedException e) { 140 e.printStackTrace(); 141 } 142 // 143 String key = "testIncr2_17353620612"; 144 long count = redisUtil.incr(key, 1); 145 if (count == 1L) { 146 redisUtil.expire(key, 10); // 缓存失效10s 147 System.err.println("短信发送成功===" + new Date()); 148 149 } else { 150 System.err.println("访问次数快===" + new Date()); 151 } 152 } 153 }); 154 threadPoolExecutor.submit(threads[i]); 155 } 156 157 while (threadPoolExecutor.getQueue().isEmpty()) { 158 threadPoolExecutor.shutdown(); 159 System.err.println("所有线程执行完毕"); 160 } 161 162 System.in.read();// 加入该代码,让主线程不挂掉 163 164 // // 启动线程 165 // for (int i = 0; i < 100; i++) { 166 // threads[i].start(); 167 // } 168 } 169 170 long count = 0L; 171 172 // 高并发下 错误的测试 递增 测试 173 @Test 174 @Ignore 175 public void testIncr3() throws Exception { 176 // 模拟发送短信的并发 177 178 // 首先开启一个线程池,创建一个专门消费短信的线程 179 // 一次性放入多个线程实例 ,实例 都是2秒请求一次 ,而10s内的只能允许一条。 也就是说我测试100个线程,只能10s一条 180 ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(6, 6, 30, TimeUnit.SECONDS, new LinkedBlockingQueue<>(100)); 181 Thread[] threads = new Thread[100]; 182 for (int i = 0; i < 100; i++) { 183 threads[i] = new Thread(new Runnable() { 184 @Override 185 public void run() { 186 // try { 187 // TimeUnit.SECONDS.sleep(2); 188 // } catch (InterruptedException e) { 189 // e.printStackTrace(); 190 // } 191 // pool-3-thread-1count===1 192 // pool-3-thread-5count===1 193 String key = "testIncr2_17353620612"; 194 count = count + 1; 195 System.err.println(Thread.currentThread().getName() + "count===" + count); 196 // 督导的count 197 // if (count == 1L) { 198 // count = count - 1; 199 // System.err.println("短信发送成功===" + new Date()); 200 // } else { 201 // System.err.println("访问次数快===" + new Date()); 202 // } 203 } 204 }); 205 threadPoolExecutor.submit(threads[i]); 206 } 207 208 while (threadPoolExecutor.getQueue().isEmpty()) { 209 threadPoolExecutor.shutdown(); 210 System.err.println("所有线程执行完毕"); 211 } 212 213 // System.in.read();// 加入该代码,让主线程不挂掉 214 } 215 216 @Test 217 @Ignore 218 public void testDecr() throws Exception { 219 String key = "Decr_17353620612"; 220 redisUtil.decr(key, 1); 221 redisUtil.expire(key, 10); // 缓存失效10s 222 Assert.assertEquals(redisUtil.get(key), 1); 223 } 224 225 @Test 226 public void testHget() throws Exception { 227 redisUtil.hset("testHget", "testHget", "testHget"); 228 Assert.assertEquals("testHget", redisUtil.hget("testHget", "testHget")); 229 230 } 231 232 @Test 233 public void testHsetStringStringObject() throws Exception { 234 redisUtil.hset("map", "testHsetStringStringObject", "testHsetStringStringObject"); 235 236 } 237 238 // 测试放在hash 里面的对象 239 @Test 240 public void testHsetObject() { 241 // 测试对象 242 TestModel testModel = new TestModel(); 243 testModel.setId(System.currentTimeMillis()); 244 testModel.setName("测试"); 245 redisUtil.hset("hash", "testModel", testModel); 246 TestModel testModel2 = (TestModel) redisUtil.hget("hash", "testModel"); 247 System.err.println(testModel2); 248 System.err.println(testModel2.getName()); 249 System.err.println(testModel2.getId()); 250 } 251 252 // 太奇妙了 放进去Long 取出来会根据大小变为相应的数据类型 253 @Test 254 public void testHsetStringStringObjectLong() throws Exception { 255 redisUtil.hset("testHsetStringStringObjectLong", "int", 100); // java.lang.Integer 读取来是inter 256 System.err.println(redisUtil.hget("testHsetStringStringObjectLong", "int").getClass().getTypeName()); 257 // Assert.assertEquals(redisUtil.hget("map", "testHsetStringStringObject"), 100L); 258 redisUtil.hset("testHsetStringStringObjectLong", "long", System.currentTimeMillis()); // java.lang.Integer 读取来是inter 259 System.err.println(redisUtil.hget("testHsetStringStringObjectLong", "long").getClass().getTypeName()); 260 261 } 262 263 @Test 264 public void testHdel() throws Exception { 265 redisUtil.hset("testHdel", "int", 100); 266 Assert.assertEquals(redisUtil.hget("testHdel", "int"), 100); 267 redisUtil.hdel("testHdel", "int"); 268 Assert.assertEquals(redisUtil.hget("testHdel", "int"), null); 269 270 } 271 272 @Test 273 public void testHHasKey() throws Exception { 274 redisUtil.hset("testHHasKey", "int", 100); 275 Assert.assertTrue(redisUtil.hHasKey("testHHasKey", "int")); 276 277 } 278 279 @Test 280 public void testHincr() throws Exception { 281 System.err.println(redisUtil.hincr("testHincr", "testHincr", 1)); 282 283 } 284 285 @Test 286 public void testHdecr() throws Exception { 287 System.err.println(redisUtil.hincr("testHincr", "testHincr", 1)); 288 } 289 290 @Test 291 public void testSGet() throws Exception { 292 redisUtil.sSet("testSGet", "testSGet1"); 293 redisUtil.sSet("testSGet", "testSGet2"); 294 System.err.println(StringUtils.join(redisUtil.sGet("testSGet"), ",")); 295 } 296 297 @Test 298 public void testSHasKey() throws Exception { 299 redisUtil.sSet("testSHasKey", "testSHasKey"); 300 Assert.assertTrue(redisUtil.sHasKey("testSHasKey", "testSHasKey")); 301 302 } 303 304 @Test 305 public void testSSet() throws Exception { 306 redisUtil.sSet("testSSet", "testSSet"); 307 308 } 309 310 @Test 311 public void testSSetAndTime() throws Exception { 312 redisUtil.sSetAndTime("testSSetAndTime", 20, "testSSetAndTime1"); 313 redisUtil.sSetAndTime("testSSetAndTime", 5, "testSSetAndTime2"); 314 System.err.println(StringUtils.join(redisUtil.sGet("testSSetAndTime"), ",")); 315 TimeUnit.SECONDS.sleep(5); 316 System.err.println(StringUtils.join(redisUtil.sGet("testSSetAndTime"), ",")); 317 TimeUnit.SECONDS.sleep(20); 318 System.err.println(StringUtils.join(redisUtil.sGet("testSSetAndTime"), ",")); 319 320 } 321 322 @Test 323 public void testSGetSetSize() throws Exception { 324 redisUtil.sSetAndTime("testSGetSetSize", 20, "testSGetSetSize1"); 325 redisUtil.sSetAndTime("testSGetSetSize", 5, "testSGetSetSize"); 326 Assert.assertEquals(redisUtil.sGetSetSize("testSGetSetSize"), 2); 327 } 328 329 @Test 330 public void testSetRemove() throws Exception { 331 redisUtil.sSetAndTime("testSetRemove", 20, "testSetRemove1"); 332 redisUtil.sSetAndTime("testSetRemove", 5, "testSetRemove"); 333 Assert.assertEquals(redisUtil.sGetSetSize("testSetRemove"), 2); 334 redisUtil.setRemove("testSetRemove", "testSetRemove"); 335 Assert.assertEquals(redisUtil.sGetSetSize("testSetRemove"), 1); 336 337 } 338 339 @Test 340 public void testLGet() throws Exception { 341 redisUtil.lSet("testLGet", "testLGet0", 10); // 10秒过期 342 redisUtil.lSet("testLGet", "testLGet1", 10); 343 // 查询三个元素 2-0+1 344 List<Object> list = redisUtil.lGet("testLGet", 0, 2); 345 System.err.println("list===" + list); 346 // 查询两个 347 List<Object> list2 = redisUtil.lGet("testLGet", 0, 1); 348 System.err.println("list2===" + list2); 349 // 查询全部 350 List<Object> list3 = redisUtil.lGet("testLGet", 0, -1); 351 System.err.println("list3===" + list3); 352 353 } 354 355 @Test 356 public void testLGetListSize() throws Exception { 357 // 看看重复元素会怎么处理 358 long size = 0; 359 redisUtil.lSet("testLGetListSize", "testLGetListSize0", 10); // 10秒过期 360 size = redisUtil.lGetListSize("testLGetListSize"); 361 System.err.println(size); 362 redisUtil.lSet("testLGetListSize", "testLGetListSize0", 10); 363 size = redisUtil.lGetListSize("testLGetListSize"); 364 System.err.println(size); 365 } 366 367 // 368 @Test 369 public void testLGetIndex() throws Exception { 370 redisUtil.lSet("testLGetIndex", "testLGetIndex0", 10); // 10秒过期 371 redisUtil.lSet("testLGetIndex", "testLGetIndex1", 10); 372 Object obj = redisUtil.lGetIndex("testLGetIndex", 0); 373 Assert.assertEquals(obj, "testLGetIndex0"); 374 } 375 376 @Test 377 public void testLSetStringObject() throws Exception { 378 redisUtil.lSet("testLSetStringObject", "testLSetStringObject0"); 379 redisUtil.lSet("testLSetStringObject", "testLSetStringObject1"); 380 redisUtil.lSet("testLSetStringObject", "testLSetStringObject2"); 381 } 382 383 @Test 384 public void testLSetStringObjectLong() throws Exception { 385 386 } 387 388 @Test 389 public void testLUpdateIndex() throws Exception { 390 redisUtil.lSet("testLUpdateIndex", "testLUpdateIndex0"); 391 redisUtil.lSet("testLUpdateIndex", "testLUpdateIndex1"); 392 redisUtil.lSet("testLUpdateIndex", "testLUpdateIndex2"); 393 Object obj = redisUtil.lUpdateIndex("testLUpdateIndex", 0, "更新的"); 394 Assert.assertEquals("更新的", obj); 395 } 396 397 @Test 398 public void testLRemove() throws Exception { 399 redisUtil.lSet("testLRemove", "testLRemove0"); 400 redisUtil.lSet("testLRemove", "testLRemove1"); 401 redisUtil.lSet("testLRemove", "testLRemove2"); 402 Object obj = redisUtil.lRemove("testLRemove", 1, "testLRemove2"); 403 } 404 405 @Data 406 class TestModel implements Serializable { 407 /** 408 * @Fields serialVersionUID : (用一句话描述这个变量表示什么) 409 */ 410 private static final long serialVersionUID = 1L; 411 private Long id; 412 private String name; 413 } 414 }
本文来自博客园,作者:荣慕平,转载请注明原文链接:https://www.cnblogs.com/rongmuping/articles/16275065.html
浙公网安备 33010602011771号