本文主要是將synchronized關鍵字用法作為例子來去解釋Java中的對象鎖和類鎖炒辉。特別的是希望能幫大家理清一些概念豪墅。
一、synchronized關鍵字
synchronized關鍵字有如下兩種用法:
1黔寇、 在需要同步的方法的方法簽名中加入synchronized關鍵字偶器。
synchronized public void getValue() {
System.out.println("getValue method thread name="
+ Thread.currentThread().getName() + " username=" + username
+ " password=" + password);
}12345
上面的代碼修飾的synchronized是非靜態(tài)方法,如果修飾的是靜態(tài)方法(static)含義是完全不一樣的缝裤。具體不一樣在哪里屏轰,后面會詳細說清楚。
synchronized static public void getValue() {
System.out.println("getValue method thread name="
+ Thread.currentThread().getName() + " username=" + username
+ " password=" + password);
}12345
2憋飞、使用synchronized塊對需要進行同步的代碼段進行同步霎苗。
public void serviceMethod() {
try {
synchronized (this) {
System.out.println("begin time=" + System.currentTimeMillis());
Thread.sleep(2000);
System.out.println("end end=" + System.currentTimeMillis());
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
上面的代碼塊是synchronized (this)
用法,還有synchronized (非this對象)
以及synchronized (類.class)
這兩種用法榛做,這些使用方式的含義也是有根本的區(qū)別的唁盏。我們先帶著這些問題繼續(xù)往下看。
4检眯、synchronized (非this對象)
我們先看看代碼實例(Run.java)
public class Run {
public static void main(String[] args) {
Service service = new Service("xiaobaoge");
ThreadA a = new ThreadA(service);
a.setName("A");
a.start();
ThreadB b = new ThreadB(service);
b.setName("B");
b.start();
}
}
class Service {
String anyString = new String();
public Service(String anyString){
this.anyString = anyString;
}
public void setUsernamePassword(String username, String password) {
try {
synchronized (anyString) {
System.out.println("線程名稱為:" + Thread.currentThread().getName()
+ "在" + System.currentTimeMillis() + "進入同步塊");
Thread.sleep(3000);
System.out.println("線程名稱為:" + Thread.currentThread().getName()
+ "在" + System.currentTimeMillis() + "離開同步塊");
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class ThreadA extends Thread {
private Service service;
public ThreadA(Service service) {
super();
this.service = service;
}
@Override
public void run() {
service.setUsernamePassword("a", "aa");
}
}
class ThreadB extends Thread {
private Service service;
public ThreadB(Service service) {
super();
this.service = service;
}
@Override
public void run() {
service.setUsernamePassword("b", "bb");
}
}
不難看出厘擂,這里線程爭奪的是anyString的對象鎖,兩個線程有競爭同一對象鎖的關系锰瘸,出現(xiàn)同步刽严。
這里的 anyString
是在jvm的字符串常量池中,地址是一樣的避凝。所以能保證多個實例
對象也能在一個鎖中舞萄。使用synchronized(任意自定義對象)進行同步操作,對象監(jiān)視器必須是同一個對象管削。不過不是同一個鹏氧,運行就是異步執(zhí)行了。這里anyString是同一個對象
同步synchronized(*.class)
代碼塊的作用其實和synchronized static
方法作用一樣佩谣。Class鎖對類的所有對象實例起作用把还。
synchronize修飾的方法和synchronize(this)
都是鎖住自己本身的對象
,synchronized(*.class)是鎖住加載類對象
,synchronized(object)是鎖住object對象
吧
轉(zhuǎn)自:https://blog.csdn.net/u013142781/article/details/51697672