Mercurial Hosting > luan
comparison src/luan/modules/ThreadLuan.java @ 1515:78d937870762
Thread.synchronized
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Sat, 30 May 2020 17:58:35 -0600 |
parents | 219f2b937f2b |
children | b89212fd04b5 |
comparison
equal
deleted
inserted
replaced
1514:af45ed10aff6 | 1515:78d937870762 |
---|---|
3 import java.io.Closeable; | 3 import java.io.Closeable; |
4 import java.util.Arrays; | 4 import java.util.Arrays; |
5 import java.util.Iterator; | 5 import java.util.Iterator; |
6 import java.util.Map; | 6 import java.util.Map; |
7 import java.util.HashMap; | 7 import java.util.HashMap; |
8 import java.util.LinkedHashMap; | |
9 import java.lang.ref.Reference; | |
10 import java.lang.ref.WeakReference; | |
11 import java.util.concurrent.Executor; | 8 import java.util.concurrent.Executor; |
12 import java.util.concurrent.Executors; | 9 import java.util.concurrent.Executors; |
13 import java.util.concurrent.ScheduledExecutorService; | 10 import java.util.concurrent.ScheduledExecutorService; |
14 import java.util.concurrent.ScheduledFuture; | 11 import java.util.concurrent.ScheduledFuture; |
15 import java.util.concurrent.TimeUnit; | 12 import java.util.concurrent.TimeUnit; |
16 import java.util.concurrent.ConcurrentHashMap; | |
17 import java.util.concurrent.locks.Lock; | 13 import java.util.concurrent.locks.Lock; |
18 import java.util.concurrent.locks.ReadWriteLock; | |
19 import java.util.concurrent.locks.ReentrantLock; | 14 import java.util.concurrent.locks.ReentrantLock; |
20 import java.util.concurrent.locks.ReentrantReadWriteLock; | 15 import goodjava.util.WeakCacheMap; |
21 import luan.Luan; | 16 import luan.Luan; |
22 import luan.LuanFunction; | 17 import luan.LuanFunction; |
23 import luan.LuanTable; | 18 import luan.LuanTable; |
24 import luan.LuanException; | 19 import luan.LuanException; |
25 import luan.LuanCloner; | 20 import luan.LuanCloner; |
54 LuanCloner cloner = new LuanCloner(LuanCloner.Type.COMPLETE); | 49 LuanCloner cloner = new LuanCloner(LuanCloner.Type.COMPLETE); |
55 final LuanFunction newFn = (LuanFunction)cloner.get(fn); | 50 final LuanFunction newFn = (LuanFunction)cloner.get(fn); |
56 exec.execute(runnable(newFn)); | 51 exec.execute(runnable(newFn)); |
57 } | 52 } |
58 | 53 |
59 private static Map<String,Reference<ScheduledFuture>> scheduleds = new ConcurrentHashMap<String,Reference<ScheduledFuture>>(); | 54 private static final Map<String,ScheduledFuture> scheduleds = new WeakCacheMap<String,ScheduledFuture>(); |
60 | 55 |
61 private static void cancel(ScheduledFuture sf,String src) { | 56 private static void cancel(ScheduledFuture sf,String src) { |
62 boolean b = sf.cancel(false); | 57 boolean b = sf.cancel(false); |
63 if( !sf.isCancelled() ) | 58 if( !sf.isCancelled() ) |
64 logger.error(src+" cancel="+b+" isCancelled="+sf.isCancelled()+" isDone="+sf.isDone()+" "+sf); | 59 logger.error(src+" cancel="+b+" isCancelled="+sf.isCancelled()+" isDone="+sf.isDone()+" "+sf); |
65 } | 60 } |
66 | 61 |
67 public static void schedule(LuanFunction fn,LuanTable options) | 62 public static synchronized void schedule(LuanFunction fn,LuanTable options) |
68 throws LuanException | 63 throws LuanException |
69 { | 64 { |
70 options = new LuanTable(options); | 65 options = new LuanTable(options); |
71 Number delay = Utils.removeNumber(options,"delay"); | 66 Number delay = Utils.removeNumber(options,"delay"); |
72 Number repeatingDelay = Utils.removeNumber(options,"repeating_delay"); | 67 Number repeatingDelay = Utils.removeNumber(options,"repeating_delay"); |
75 if( repeatingDelay!=null && repeatingRate!=null ) | 70 if( repeatingDelay!=null && repeatingRate!=null ) |
76 throw new LuanException("can't define both repeating_delay and repeating_rate"); | 71 throw new LuanException("can't define both repeating_delay and repeating_rate"); |
77 boolean repeating = repeatingDelay!=null || repeatingRate!=null; | 72 boolean repeating = repeatingDelay!=null || repeatingRate!=null; |
78 Utils.checkEmpty(options); | 73 Utils.checkEmpty(options); |
79 if( id != null ) { | 74 if( id != null ) { |
80 Reference<ScheduledFuture> ref = scheduleds.remove(id); | 75 ScheduledFuture sf = scheduleds.remove(id); |
81 if( ref != null ) { | 76 if( sf != null ) |
82 ScheduledFuture sf = ref.get(); | 77 cancel(sf,"id "+id); |
83 if( sf != null ) | |
84 cancel(sf,"id "+id); | |
85 } | |
86 } | 78 } |
87 Luan luan = fn.luan(); | 79 Luan luan = fn.luan(); |
88 LuanCloner cloner = new LuanCloner(LuanCloner.Type.COMPLETE); | 80 LuanCloner cloner = new LuanCloner(LuanCloner.Type.COMPLETE); |
89 final Luan newLuan = (Luan)cloner.clone(luan); | 81 final Luan newLuan = (Luan)cloner.clone(luan); |
90 final LuanFunction newFn = (LuanFunction)cloner.get(fn); | 82 final LuanFunction newFn = (LuanFunction)cloner.get(fn); |
109 cancel(sf,"gc"); | 101 cancel(sf,"gc"); |
110 } | 102 } |
111 }; | 103 }; |
112 luan.registry().put(c,c); // cancel on gc | 104 luan.registry().put(c,c); // cancel on gc |
113 if( id != null ) | 105 if( id != null ) |
114 scheduleds.put(id,new WeakReference<ScheduledFuture>(sf)); | 106 scheduleds.put(id,sf); |
115 } | 107 } |
116 | 108 |
117 /* | 109 /* |
118 public static class GlobalMap { | 110 public static class GlobalMap { |
119 | 111 |
251 public static synchronized void removeGlobalCallable(String name) { | 243 public static synchronized void removeGlobalCallable(String name) { |
252 callableMap.remove(name); | 244 callableMap.remove(name); |
253 } | 245 } |
254 | 246 |
255 | 247 |
256 public static void lock(Lock lock) | 248 public static Object runInLock(Lock lock,long timeout,LuanFunction fn,Object... args) |
257 throws LuanException, InterruptedException | 249 throws LuanException, InterruptedException |
258 { | 250 { |
259 if( !lock.tryLock(10,TimeUnit.MINUTES) ) | 251 if( !lock.tryLock(timeout,TimeUnit.MILLISECONDS) ) |
260 throw new LuanException("failed to acquire lock"); | 252 throw new LuanException("failed to acquire lock"); |
261 } | |
262 | |
263 public static Object runInLock(Lock lock,LuanFunction fn,Object... args) | |
264 throws LuanException, InterruptedException | |
265 { | |
266 lock(lock); | |
267 try { | 253 try { |
268 return fn.call(args); | 254 return fn.call(args); |
269 } finally { | 255 } finally { |
270 lock.unlock(); | 256 lock.unlock(); |
271 } | 257 } |
272 } | 258 } |
273 | 259 |
260 private static final Map<String,Lock> locks = new WeakCacheMap<String,Lock>(); | |
261 | |
262 public static synchronized Lock getLock(String key) { | |
263 Lock lock = locks.get(key); | |
264 if( lock == null ) { | |
265 lock = new ReentrantLock(); | |
266 locks.put(key,lock); | |
267 } | |
268 return lock; | |
269 } | |
270 | |
274 } | 271 } |