/** * 對任務隊列的串行訪問 */ 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等查看棧信息。
完。
不吝指正。