10
10
11
11
public class Chapter02 {
12
12
13
- public static final void main (String [] args ) throws InterruptedException {
13
+ public static void main (String [] args ) throws InterruptedException {
14
14
new Chapter02 ().run ();
15
15
}
16
16
@@ -163,15 +163,15 @@ public void testCacheRequest(Jedis conn) {
163
163
}
164
164
165
165
/**
166
- * 代码清单 2-1
166
+ * 代码清单 2-1 管理令牌-查询令牌
167
167
*/
168
168
public String checkToken (Jedis conn , String token ) {
169
169
// 尝试获取并返回令牌对应的用户。
170
170
return conn .hget ("login:" , token );
171
171
}
172
172
173
173
/**
174
- * 代码清单 2-2 代码清单 2-9
174
+ * 代码清单 2-2、 2-9 管理令牌-更新令牌
175
175
*/
176
176
public void updateToken (Jedis conn , String token , String user , String item ) {
177
177
// 获取当前时间戳。
@@ -190,130 +190,15 @@ public void updateToken(Jedis conn, String token, String user, String item) {
190
190
}
191
191
192
192
/**
193
- * 代码清单 2-4
194
- */
195
- public void addToCart (Jedis conn , String session , String item , int count ) {
196
- if (count <= 0 ) {
197
- // 从购物车里面移除指定的商品。
198
- conn .hdel ("cart:" + session , item );
199
- } else {
200
- // 将指定的商品添加到购物车。
201
- conn .hset ("cart:" + session , item , String .valueOf (count ));
202
- }
203
- }
204
-
205
- /**
206
- * 代码清单 2-7
207
- */
208
- public void scheduleRowCache (Jedis conn , String rowId , int delay ) {
209
- // 先设置数据行的延迟值。
210
- conn .zadd ("delay:" , delay , rowId );
211
- // 立即缓存数据行。
212
- conn .zadd ("schedule:" , System .currentTimeMillis () / 1000 , rowId );
213
- }
214
-
215
- /**
216
- * 代码清单 2-6
217
- */
218
- public String cacheRequest (Jedis conn , String request , Callback callback ) {
219
- // 对于不能被缓存的请求,直接调用回调函数。
220
- if (!canCache (conn , request )) {
221
- return callback != null ? callback .call (request ) : null ;
222
- }
223
-
224
- // 将请求转换成一个简单的字符串键,方便之后进行查找。
225
- String pageKey = "cache:" + hashRequest (request );
226
- // 尝试查找被缓存的页面。
227
- String content = conn .get (pageKey );
228
-
229
- if (content == null && callback != null ) {
230
- // 如果页面还没有被缓存,那么生成页面。
231
- content = callback .call (request );
232
- // 将新生成的页面放到缓存里面。
233
- conn .setex (pageKey , 300 , content );
234
- }
235
-
236
- // 返回页面。
237
- return content ;
238
- }
239
-
240
- /**
241
- * 代码清单 2-11
242
- */
243
- public boolean canCache (Jedis conn , String request ) {
244
- try {
245
- URL url = new URL (request );
246
- HashMap <String , String > params = new HashMap <>();
247
- if (url .getQuery () != null ) {
248
- for (String param : url .getQuery ().split ("&" )) {
249
- String [] pair = param .split ("=" , 2 );
250
- params .put (pair [0 ], pair .length == 2 ? pair [1 ] : null );
251
- }
252
- }
253
-
254
- // 尝试从页面里面取出商品ID。
255
- String itemId = extractItemId (params );
256
- // 检查这个页面能否被缓存以及这个页面是否为商品页面。
257
- if (itemId == null || isDynamic (params )) {
258
- return false ;
259
- }
260
- // 取得商品的浏览次数排名。
261
- Long rank = conn .zrank ("viewed:" , itemId );
262
- // 根据商品的浏览次数排名来判断是否需要缓存这个页面。
263
- return rank != null && rank < 10000 ;
264
- } catch (MalformedURLException mue ) {
265
- return false ;
266
- }
267
- }
268
-
269
- public boolean isDynamic (Map <String , String > params ) {
270
- return params .containsKey ("_" );
271
- }
272
-
273
- public String extractItemId (Map <String , String > params ) {
274
- return params .get ("item" );
275
- }
276
-
277
- public String hashRequest (String request ) {
278
- return String .valueOf (request .hashCode ());
279
- }
280
-
281
- public interface Callback {
282
-
283
- String call (String request );
284
-
285
- }
286
-
287
- public static class Inventory {
288
-
289
- private String id ;
290
-
291
- private String data ;
292
-
293
- private long time ;
294
-
295
- private Inventory (String id ) {
296
- this .id = id ;
297
- this .data = "data to cache..." ;
298
- this .time = System .currentTimeMillis () / 1000 ;
299
- }
300
-
301
- public static Inventory get (String id ) {
302
- return new Inventory (id );
303
- }
304
-
305
- }
306
-
307
- /**
308
- * 代码清单 2-3
193
+ * 代码清单 2-3 管理令牌-清理令牌
309
194
*/
310
195
public static class CleanSessionsThread extends Thread {
311
196
312
197
private Jedis conn ;
313
198
314
199
private int limit ;
315
200
316
- private boolean quit ;
201
+ private volatile boolean quit ;
317
202
318
203
public CleanSessionsThread (int limit ) {
319
204
this .conn = new Jedis ("localhost" );
@@ -360,10 +245,23 @@ public void run() {
360
245
361
246
}
362
247
248
+ /**
249
+ * 代码清单 2-4
250
+ */
251
+ public void addToCart (Jedis conn , String session , String item , int count ) {
252
+ if (count <= 0 ) {
253
+ // 从购物车里面移除指定的商品。
254
+ conn .hdel ("cart:" + session , item );
255
+ } else {
256
+ // 将指定的商品添加到购物车。
257
+ conn .hset ("cart:" + session , item , String .valueOf (count ));
258
+ }
259
+ }
260
+
363
261
/**
364
262
* 代码清单 2-5
365
263
*/
366
- public class CleanFullSessionsThread extends Thread {
264
+ public static class CleanFullSessionsThread extends Thread {
367
265
368
266
private Jedis conn ;
369
267
@@ -414,9 +312,44 @@ public void run() {
414
312
}
415
313
416
314
/**
417
- * 代码清单 2-8
315
+ * 代码清单 2-6 页面缓存
418
316
*/
419
- public class CacheRowsThread extends Thread {
317
+ public String cacheRequest (Jedis conn , String request , Callback callback ) {
318
+ // 对于不能被缓存的请求,直接调用回调函数。
319
+ if (!canCache (conn , request )) {
320
+ return callback != null ? callback .call (request ) : null ;
321
+ }
322
+
323
+ // 将请求转换成一个简单的字符串键,方便之后进行查找。
324
+ String pageKey = "cache:" + hashRequest (request );
325
+ // 尝试查找被缓存的页面。
326
+ String content = conn .get (pageKey );
327
+
328
+ if (content == null && callback != null ) {
329
+ // 如果页面还没有被缓存,那么生成页面。
330
+ content = callback .call (request );
331
+ // 将新生成的页面放到缓存里面。
332
+ conn .setex (pageKey , 300 , content );
333
+ }
334
+
335
+ // 返回页面。
336
+ return content ;
337
+ }
338
+
339
+ /**
340
+ * 代码清单 2-7 数据行缓存-记录缓存时机
341
+ */
342
+ public void scheduleRowCache (Jedis conn , String rowId , int delay ) {
343
+ // 先设置数据行的延迟值。
344
+ conn .zadd ("delay:" , delay , rowId );
345
+ // 立即缓存数据行。
346
+ conn .zadd ("schedule:" , System .currentTimeMillis () / 1000 , rowId );
347
+ }
348
+
349
+ /**
350
+ * 代码清单 2-8 数据行缓存-定时更新数据行缓存
351
+ */
352
+ public static class CacheRowsThread extends Thread {
420
353
421
354
private Jedis conn ;
422
355
@@ -471,4 +404,71 @@ public void run() {
471
404
472
405
}
473
406
407
+ /**
408
+ * 代码清单 2-11
409
+ */
410
+ public boolean canCache (Jedis conn , String request ) {
411
+ try {
412
+ URL url = new URL (request );
413
+ HashMap <String , String > params = new HashMap <>();
414
+ if (url .getQuery () != null ) {
415
+ for (String param : url .getQuery ().split ("&" )) {
416
+ String [] pair = param .split ("=" , 2 );
417
+ params .put (pair [0 ], pair .length == 2 ? pair [1 ] : null );
418
+ }
419
+ }
420
+
421
+ // 尝试从页面里面取出商品ID。
422
+ String itemId = extractItemId (params );
423
+ // 检查这个页面能否被缓存以及这个页面是否为商品页面。
424
+ if (itemId == null || isDynamic (params )) {
425
+ return false ;
426
+ }
427
+ // 取得商品的浏览次数排名。
428
+ Long rank = conn .zrank ("viewed:" , itemId );
429
+ // 根据商品的浏览次数排名来判断是否需要缓存这个页面。
430
+ return rank != null && rank < 10000 ;
431
+ } catch (MalformedURLException mue ) {
432
+ return false ;
433
+ }
434
+ }
435
+
436
+ public boolean isDynamic (Map <String , String > params ) {
437
+ return params .containsKey ("_" );
438
+ }
439
+
440
+ public String extractItemId (Map <String , String > params ) {
441
+ return params .get ("item" );
442
+ }
443
+
444
+ public String hashRequest (String request ) {
445
+ return String .valueOf (request .hashCode ());
446
+ }
447
+
448
+ public interface Callback {
449
+
450
+ String call (String request );
451
+
452
+ }
453
+
454
+ public static class Inventory {
455
+
456
+ private String id ;
457
+
458
+ private String data ;
459
+
460
+ private long time ;
461
+
462
+ private Inventory (String id ) {
463
+ this .id = id ;
464
+ this .data = "data to cache..." ;
465
+ this .time = System .currentTimeMillis () / 1000 ;
466
+ }
467
+
468
+ public static Inventory get (String id ) {
469
+ return new Inventory (id );
470
+ }
471
+
472
+ }
473
+
474
474
}
0 commit comments