/** * 对任务队列的串行访问 */ public class WorkThread extends Thread { private final BlockingQueue<Runnable> queue; public WorkThread(BlockingQueue<Runnable> queue){ this.queue = queue; } public void run(){ while (true){ try { Runnable task = queue.take(); //此处为程序的串行部分 task.run(); } catch (InterruptedException e) { break; } } } }
//object只能由当前线程所访问,因此会去掉锁 synchronized(new Object()){ // do sth. } //局部变量v不会逃逸, 所以线程私有,优化会取消加锁 public String getStoogeNames(){ Vector<String> v = new Vector<>(); v.add("Hello"); v.add("World"); return v.toString(); }
1. 阻塞时,cpu时间片未用完前被交换出去。 java
2. 请求的锁或资源可用时,再次被切换回来。 ios
1. 减小锁的持有时间。 web
2. 下降锁的请求频率。 数据库
3. 使用带有协调机制的独占锁。 windows
/** * 没必要要的长时间持有锁 */ public class AttrbuteStore { private final Map<String, String> attributes = new HashMap<String, String>(); /** * synchronized锁住当前对象 */ public synchronized boolean userLocationMatcher(String name, String regexp){ String key = "users." + name + ".location"; String location = attributes.get(key); if (location == null) return false; else return Pattern.matches(regexp, location); } }
可修改上面的方法: 网络
public boolean userLocationMatcher(String name, String regexp){ String key = "users." + name + ".location"; String location = null; synchronized(this){ location = attributes.get(key); //仅锁住共享对象 } if (location == null) return false; else return Pattern.matches(regexp, location); }
更好的方式是将attributes用并发容器来实现,如ConcurrentHashMap等。 数据结构
/** * 多个状态由一个锁来保护 */ public class ServerStatus { public final Set<String> users; private final Set<String> queries; ... public synchronized void addUser(String u){ users.add(u); } public synchronized void addQuery(String q){ queries.add(q); } }
将锁进行分解: 并发
/** * 多个状态由多个锁来保护 */ public class BetterServerStatus { public final Set<String> users; private final Set<String> queries; ... public void addUser(String u){ synchronized(users){ users.add(u); } } public void addQuery(String q){ synchronized(queries){ queries.add(q); } } }
1. 负载不充足。 框架
2. I/O密集。*nix可用iostat, windows用perfmon。 性能
3. 外部限制。如数据库服务,web服务等。
4. 锁竞争。可经过jstack等查看栈信息。
完。
不吝指正。