1. 样例1
public class SycString {
public static void sys(String str) throws InterruptedException {
synchronized (str) {
System.out.println(str);
TimeUnit.SECONDS.sleep(5);
}
}
public static void main(String[] args) {
ExecutorService es = Executors.newFixedThreadPool(10);
Interner<String> pool = Interners.newWeakInterner();
for(int i = 0; i < 5;i++) {
es.execute(()->{try {
SycString.sys(pool.intern(new String("test")));
} catch (Exception e) {
e.printStackTrace();
}});
}
}
}
2.样例2
//类1- SynStringTest
package com.tinygao.thread.synstring;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.function.BiConsumer;
import com.google.common.base.Stopwatch;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class SynStringTest {
private final static SynString synStr = new SynString();
private final static Stopwatch sw = Stopwatch.createStarted();
private static BiConsumer<SynString, String> function = (x, y)->{
synchronized (x.getStringLock(y)) {
log.info("Get lock: {}", y);
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
public static void main(String[] args) throws InterruptedException {
final ExecutorService executorService = Executors.newFixedThreadPool(
4,
new ThreadFactoryBuilder().setNameFormat("SynString-%d").build()
);
executorService.submit(()->{
doTask("test");
});
executorService.submit(()->{
doTask("test");
});
executorService.submit(()->{
doTask("test1");
});
executorService.shutdown();
executorService.awaitTermination(1, TimeUnit.DAYS);
sw.stop();
}
private static void doTask(String lockStr) {
function.accept(synStr, lockStr);
log.info("Do get lockStr successed waste time elapsed : {} ms", sw.elapsed(TimeUnit.MILLISECONDS));
}
}
//类2- SynString
package com.tinygao.thread.synstring;
import java.util.concurrent.ConcurrentMap;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class SynString {
private static ConcurrentMap<String,Object> parMap = Maps.newConcurrentMap();
public Object getStringLock(String string) {
Object lock = this;
if(parMap != null) {
Object newLock = new Object();
lock = parMap.putIfAbsent(string, newLock);
if(lock == null) {
lock = newLock;
}
}
return lock;
}
public static void main(String[] args) {
Object result = parMap.putIfAbsent("h", "g");
log.info("Get result: {}", result);
}
}
#2. 具体应用
private static Interner<String> pool = Interners.newWeakInterner();
//这种在分布式系统中会有问题
public static void copyFileToLocal(String hdfsSrc,String localFile) throws IOException{
synchronized (pool.intern(localFile)) {
Path dstLock = new Path(localFile+".lock");
if(localFs.exists(dstLock)) {
log.warn("CopyFileToLocal the file :{} is lock", localFile);
throw new RuntimeException("CopyFileToLocal the file "+localFile+" is lock");
}
localFs.createNewFile(dstLock);
try {
doCopyMeger(hdfsSrc, localFile);
} finally {
localFs.delete(dstLock, false);
}
}
}