try catch用法_synchronized用法总结
synchronized :java內置關鍵字,被保存在對象頭中,而一個對象則是由對象頭、實例數據、對其填充三部分組成。
很多時候大家伙都慣性地將synchronized稱為一個重量級鎖,理由是synchronized性能開銷較重;這在JDK1.6之間這樣說是沒毛病的,但是在JDK1.6及以后,還這樣認為那就欠妥了,因為在JDK1.6及以后JVM層面對它作了優化,可以由輕到重分為:偏向鎖->輕量級鎖->重量級鎖;并且可自動進行鎖粒度的切換升級。所以從性能開銷的程度來講,已經變得和Lock相差無幾了!
一般來說synchronized有三種用法:
一、作用于靜態方法
給當前類加鎖,又可稱之靜態方法鎖:可以修飾在靜態方法名前: public static synchronized void inc() :
又可以修飾在靜態方法里的代碼塊(如下): synchronized (Method.class){}
package com.wuqx.demo;public class Method { private static int count = 0; public static void inc(){ synchronized (Method.class){ try { Thread.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } count ++; } } public static void main(String[] args) { for (int i = 0; i < 100; i++) { //不要new太多的線程,避免操作系統假死,出現找不到主類的錯誤 new Thread(()->Method.inc()).start(); } while(Thread.activeCount()>1){ //這里也可以使用Thread.sleep()方法進行阻塞,避免得到錯誤的結果 Thread.yield(); } System.out.println("result:"+Method.count); }}總結:可以保證多個實例對象調用靜態方法時保證其安全性
二、作用于實例方法
即對象鎖,對同一個對象加鎖,保證多個線程訪問同一個對象時線程的安全,進入同步代碼前要獲得當前對象的鎖,
(1)多個線程對同一對象進行訪問,代碼清單如下:
package t;public class Method implements Runnable{ private static int count = 0; public synchronized void run(){ for(int i=0; i<5; i++){ System.out.println(Thread.currentThread().getName()+":"+count++); } } public static void main(String[] args) { Method md = new Method(); Thread thread1 = new Thread(md,"thread1"); Thread thread2 = new Thread(md,"thread2"); thread1.start(); thread2.start(); int i = 0; while(Thread.activeCount()>1){ System.out.println("第"+i+++"次出讓系統資源"); Thread.yield(); } System.out.println("result:"+Method.count); }}運行結果:
?
(2)多個線程對不同對象訪問,則會造成線程的安全問題;因為兩個對象之間沒有關系,是獨立的,內存地址,保存在對象頭里的鎖也不相同,所以會造成線程安全問題。代碼清單如下(兩個線程執行兩個對象):
package t;
public class Method implements Runnable{
private static int count = 0;
public synchronized void run(){
for(int i=0; i<5; i++){
System.out.println(Thread.currentThread().getName()+":"+count++);
}
}
public static void main(String[] args) {
Method md = new Method();
Method md1 = new Method();
Thread thread1 = new Thread(md,"thread1");
Thread thread2 = new Thread(md1,"thread2");
thread1.start();
thread2.start();
}
}
??運行結果如下:
?
可見這種情況只能通過將run方法里的方法靜態化,通過類鎖去解決:代碼清單如下:
??package t;public class Method implements Runnable{ private static int count = 0; public void run(){ //這里加與不加synchronized 效果都一樣,可以思考下為什么 inc(); } public static synchronized void inc(){ for(int i=0; i<5; i++){ System.out.println(Thread.currentThread().getName()+":"+count++); } } public static void main(String[] args) { Method md = new Method(); Method md1 = new Method(); Thread thread1 = new Thread(md,"thread1"); Thread thread2 = new Thread(md1,"thread2"); thread1.start(); thread2.start(); }}運行結果如下:
?
三、修飾代碼快
寫法為synchronized(obj){},實際工程上都用寫為synchronized(this){}, 這是對于多個線程訪問同一對象,代碼清單如下;如果多個線程訪問不同對象,那么這樣寫還是不能保證線程的安全,因為將對象不同,鎖也就不是同一把鎖了,這樣就同樣需要類鎖去實現了。
package t;
public class Method implements Runnable{
private static int count = 0;
public void run(){
inc();
}
public void inc(){
synchronized(this){
for(int i=0; i<5; i++){
System.out.println(Thread.currentThread().getName()+":"+count++);
}
}
}
public static void main(String[] args) {
Method md = new Method();
Thread thread1 = new Thread(md,"thread1");
Thread thread2 = new Thread(md,"thread2");
thread1.start();
thread2.start();
}
}
運行結果:
???
如果覺得對自己有幫助的話,不妨關注點贊轉發支持下哦!??
相關導讀:
synchronized與Lock的區別
總結
以上是生活随笔為你收集整理的try catch用法_synchronized用法总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: panda 透视表 计算比例_用案例教你
- 下一篇: python第一周心得体会_Python