try catch用法_synchronized用法总结
synchronized :java內(nèi)置關(guān)鍵字,被保存在對(duì)象頭中,而一個(gè)對(duì)象則是由對(duì)象頭、實(shí)例數(shù)據(jù)、對(duì)其填充三部分組成。
很多時(shí)候大家伙都慣性地將synchronized稱為一個(gè)重量級(jí)鎖,理由是synchronized性能開銷較重;這在JDK1.6之間這樣說(shuō)是沒(méi)毛病的,但是在JDK1.6及以后,還這樣認(rèn)為那就欠妥了,因?yàn)樵贘DK1.6及以后JVM層面對(duì)它作了優(yōu)化,可以由輕到重分為:偏向鎖->輕量級(jí)鎖->重量級(jí)鎖;并且可自動(dòng)進(jìn)行鎖粒度的切換升級(jí)。所以從性能開銷的程度來(lái)講,已經(jīng)變得和Lock相差無(wú)幾了!
一般來(lái)說(shuō)synchronized有三種用法:
一、作用于靜態(tài)方法
給當(dāng)前類加鎖,又可稱之靜態(tài)方法鎖:可以修飾在靜態(tài)方法名前: public static synchronized void inc() :
又可以修飾在靜態(tài)方法里的代碼塊(如下): 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太多的線程,避免操作系統(tǒng)假死,出現(xiàn)找不到主類的錯(cuò)誤 new Thread(()->Method.inc()).start(); } while(Thread.activeCount()>1){ //這里也可以使用Thread.sleep()方法進(jìn)行阻塞,避免得到錯(cuò)誤的結(jié)果 Thread.yield(); } System.out.println("result:"+Method.count); }}總結(jié):可以保證多個(gè)實(shí)例對(duì)象調(diào)用靜態(tài)方法時(shí)保證其安全性
二、作用于實(shí)例方法
即對(duì)象鎖,對(duì)同一個(gè)對(duì)象加鎖,保證多個(gè)線程訪問(wèn)同一個(gè)對(duì)象時(shí)線程的安全,進(jìn)入同步代碼前要獲得當(dāng)前對(duì)象的鎖,
(1)多個(gè)線程對(duì)同一對(duì)象進(jìn)行訪問(wèn),代碼清單如下:
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+++"次出讓系統(tǒng)資源"); Thread.yield(); } System.out.println("result:"+Method.count); }}運(yùn)行結(jié)果:
?
(2)多個(gè)線程對(duì)不同對(duì)象訪問(wèn),則會(huì)造成線程的安全問(wèn)題;因?yàn)閮蓚€(gè)對(duì)象之間沒(méi)有關(guān)系,是獨(dú)立的,內(nèi)存地址,保存在對(duì)象頭里的鎖也不相同,所以會(huì)造成線程安全問(wèn)題。代碼清單如下(兩個(gè)線程執(zhí)行兩個(gè)對(duì)象):
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();
}
}
??運(yùn)行結(jié)果如下:
?
可見這種情況只能通過(guò)將run方法里的方法靜態(tài)化,通過(guò)類鎖去解決:代碼清單如下:
??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(); }}運(yùn)行結(jié)果如下:
?
三、修飾代碼快
寫法為synchronized(obj){},實(shí)際工程上都用寫為synchronized(this){}, 這是對(duì)于多個(gè)線程訪問(wèn)同一對(duì)象,代碼清單如下;如果多個(gè)線程訪問(wèn)不同對(duì)象,那么這樣寫還是不能保證線程的安全,因?yàn)閷?duì)象不同,鎖也就不是同一把鎖了,這樣就同樣需要類鎖去實(shí)現(xiàn)了。
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();
}
}
運(yùn)行結(jié)果:
???
如果覺(jué)得對(duì)自己有幫助的話,不妨關(guān)注點(diǎn)贊轉(zhuǎn)發(fā)支持下哦!??
相關(guān)導(dǎo)讀:
synchronized與Lock的區(qū)別
總結(jié)
以上是生活随笔為你收集整理的try catch用法_synchronized用法总结的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: panda 透视表 计算比例_用案例教你
- 下一篇: vs unity shader插件_一些