久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

synchronized

 魚的眼界 2012-07-06
 synchronized 關(guān)鍵字,,代表這個(gè)方法加鎖,相當(dāng)于不管哪一個(gè)線程(例如線程A),,運(yùn)行到這個(gè)方法時(shí),都要檢查有沒有其它線程B(或者C、 D等)正在用這個(gè)方法,,有的話要等正在使用synchronized方法的線程B(或者C ,、D)運(yùn)行完這個(gè)方法后再運(yùn)行此線程A,沒有的話,直接運(yùn)行。它包括兩種用法:synchronized 方法和 synchronized 塊,。

1. synchronized 方法:

  聲明是為了定義變量的作用范圍和作用域
  通過在方法聲明中加入 synchronized關(guān)鍵字來聲明 synchronized 方法,。如:
  public synchronized void accessVal(int newVal);
  synchronized 方法控制對(duì)類成員變量的訪問:每個(gè)類實(shí)例對(duì)應(yīng)一把鎖,每個(gè) synchronized 方法都必須獲得調(diào)用該方法的類實(shí)例的鎖方能執(zhí)行,,否則所屬線程阻塞,,方法一旦執(zhí)行,,就獨(dú)占該鎖,直到從該方法返回時(shí)才將鎖釋放,,此后被阻塞的線程方能獲得該鎖,,重新進(jìn)入可執(zhí)行狀態(tài)。這種機(jī)制確保了同一時(shí)刻對(duì)于每一個(gè)類實(shí)例,,其所有聲明為 synchronized 的成員函數(shù)中至多只有一個(gè)處于可執(zhí)行狀態(tài)(因?yàn)橹炼嘀挥幸粋€(gè)能夠獲得該類實(shí)例對(duì)應(yīng)的鎖),,從而有效避免了類成員變量的訪問沖突(只要所有可能訪問類成員變量的方法均被聲明為 synchronized)。
  在 Java 中,,不光是類實(shí)例,,每一個(gè)類也對(duì)應(yīng)一把鎖,這樣我們也可將類的靜態(tài)成員函數(shù)聲明為 synchronized ,,以控制其對(duì)類的靜態(tài)成員變量的訪問,。
  synchronized 方法的缺陷:若將一個(gè)大的方法聲明為synchronized 將會(huì)大大影響效率,典型地,,若將線程類的方法 run() 聲明為 synchronized ,,由于在線程的整個(gè)生命期內(nèi)它一直在運(yùn)行,因此將導(dǎo)致它對(duì)本類任何 synchronized 方法的調(diào)用都永遠(yuǎn)不會(huì)成功,。當(dāng)然我們可以通過將訪問類成員變量的代碼放到專門的方法中,,將其聲明為 synchronized ,并在主方法中調(diào)用來解決這一問題,,但是 Java 為我們提供了更好的解決辦法,,那就是 synchronized 塊。

2. synchronized 塊:

  通過 synchronized關(guān)鍵字來聲明synchronized 塊,。語法如下:
  synchronized(syncObject) {
  //允許訪問控制的代碼
  }
  synchronized 塊是這樣一個(gè)代碼塊,,其中的代碼必須獲得對(duì)象 syncObject (如前所述,可以是類實(shí)例或類)的鎖方能執(zhí)行,,具體機(jī)制同前所述,。由于可以針對(duì)任意代碼塊,且可任意指定上鎖的對(duì)象,,故靈活性較高,。

對(duì)synchronized(this)的一些理解

  一、當(dāng)兩個(gè)并發(fā)線程訪問同一個(gè)對(duì)象object中的這個(gè)synchronized(this)同步代碼塊時(shí),,一個(gè)時(shí)間內(nèi)只能有一個(gè)線程得到執(zhí)行,。另一個(gè)線程必須等待當(dāng)前線程執(zhí)行完這個(gè)代碼塊以后才能執(zhí)行該代碼塊。
  二,、當(dāng)一個(gè)線程訪問object的一個(gè)synchronized(this)同步代碼塊時(shí),,其他線程對(duì)object中所有其它synchronized(this)同步代碼塊的訪問將被阻塞。
  三,、然而,,當(dāng)一個(gè)線程訪問object的一個(gè)synchronized(this)同步代碼塊時(shí),,另一個(gè)線程仍然可以訪問該object中的除synchronized(this)同步代碼塊以外的部分。
  四,、第三個(gè)例子同樣適用其它同步代碼塊,。也就是說,當(dāng)一個(gè)線程訪問object的一個(gè)synchronized(this)同步代碼塊時(shí),,它就獲得了這個(gè)object的對(duì)象鎖,。結(jié)果,其它線程對(duì)該object對(duì)象所有同步代碼部分的訪問都被暫時(shí)阻塞,。
  五,、以上規(guī)則對(duì)其它對(duì)象鎖同樣適用

synchronized的4種用法

  
1.方法聲明時(shí)使用,放在范圍操作符(public等)之后,,返回類型聲明(void等)之前,。即一次只能有一個(gè)線程進(jìn)入該方法,,其他線程要想在此時(shí)調(diào)用該方法,,只能排隊(duì)等候,當(dāng)前線程(就是在synchronized方法內(nèi)部的線程)執(zhí)行完該方法后,,別的線程才能進(jìn)入,。
例如:
public synchronized void synMethod() {
//方法體
}
2.對(duì)某一代碼塊使用,synchronized后跟括號(hào),,括號(hào)里是變量,,這樣,一次只有一個(gè)線程進(jìn)入該代碼塊,。例如:
public int synMethod(int a1){
synchronized(a1) {
//一次只能有一個(gè)線程進(jìn)入
}
}
3.synchronized后面括號(hào)里是一對(duì)象,,此時(shí),線程獲得的是對(duì)象鎖,。例如:
public class MyThread implements Runnable {
public static void main(String args[]) {
MyThread mt = new MyThread();
Thread t1 = new Thread(mt, "t1");
Thread t2 = new Thread(mt, "t2");
Thread t3 = new Thread(mt, "t3");
Thread t4 = new Thread(mt, "t4");
Thread t5 = new Thread(mt, "t5");
Thread t6 = new Thread(mt, "t6");
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
t6.start();
}
public void run() {
synchronized (this) {
System.out.println(Thread.currentThread().getName());
}
}
}
對(duì)于3,如果線程進(jìn)入,,則得到對(duì)象鎖,那么別的線程在該類所有對(duì)象上的任何操作都不能進(jìn)行,。在對(duì)象級(jí)使用鎖通常是一種比較粗糙的方法,。為什么要將整個(gè)對(duì)象都上鎖,而不允許其他線程短暫地使用對(duì)象中其他同步方法來訪問共享資源,?如果一個(gè)對(duì)象擁有多個(gè)資源,,就不需要只為了讓一個(gè)線程使用其中一部分資源,就將所有線程都鎖在外面,。由于每個(gè)對(duì)象都有鎖,,可以如下所示使用虛擬對(duì)象來上鎖:
class FineGrainLock {
MyMemberClass x, y;
Object xlock = new Object(), ylock = new Object();
public void foo() {
synchronized(xlock) {
//access x here
}
//do something here - but don‘t use shared resources
synchronized(ylock) {
//access y here
}
}
public void bar() {
synchronized(this) {
//access both x and y here
}
//do something here - but don‘t use shared resources
}
}
4.synchronized后面括號(hào)里是類。例如:
class ArrayWithLockOrder{
private static long num_locks = 0;
private long lock_order;
private int[] arr;
public ArrayWithLockOrder(int[] a)
{
arr = a;
synchronized(ArrayWithLockOrder.class) {//-----------------------------------------這里
num_locks++; // 鎖數(shù)加 1,。
lock_order = num_locks; // 為此對(duì)象實(shí)例設(shè)置唯一的 lock_order,。
}
}
public long lockOrder()
{
return lock_order;
}
public int[] array()
{
return arr;
}
}
class SomeClass implements Runnable
{
public int sumArrays(ArrayWithLockOrder a1,
ArrayWithLockOrder a2)
{
int value = 0;
ArrayWithLockOrder first = a1; // 保留數(shù)組引用的一個(gè)
ArrayWithLockOrder last = a2; // 本地副本,。
int size = a1.array().length;
if (size == a2.array().length)
{
if (a1.lockOrder() > a2.lockOrder()) // 確定并設(shè)置對(duì)象的鎖定
{ // 順序。
first = a2;
last = a1;
}
synchronized(first) { // 按正確的順序鎖定對(duì)象,。
synchronized(last) {
int[] arr1 = a1.array();
int[] arr2 = a2.array();
for (int i=0; i value += arr1[i] + arr2[i];
}
}
}
return value;
}
public void run() {
//...
}
}
對(duì)于4,如果線程進(jìn)入,,則線程在該類中所有操作不能進(jìn)行,包括靜態(tài)變量和靜態(tài)方法,,實(shí)際上,,對(duì)于含有靜態(tài)方法和靜態(tài)變量的代碼塊的同步,我們通常用4來加鎖,。
以上4種之間的關(guān)系:
鎖是和對(duì)象相關(guān)聯(lián)的,,每個(gè)對(duì)象有一把鎖,為了執(zhí)行synchronized語句,,線程必須能夠獲得synchronized語句中表達(dá)式指定的對(duì)象的鎖,,一個(gè)對(duì)象只有一把鎖,被一個(gè)線程獲得之后它就不再擁有這把鎖,,線程在執(zhí)行完synchronized語句后,,將獲得鎖交還給對(duì)象。
在方法前面加上synchronized修飾符即可以將一個(gè)方法聲明為同步化方法,。同步化方法在執(zhí)行之前獲得一個(gè)鎖,。如果這是一個(gè)類方法,那么獲得的鎖是和聲明方法的類相關(guān)的Class類對(duì)象的鎖,。如果這是一個(gè)實(shí)例方法,,那么此鎖是this對(duì)象的鎖。synchronzied塊后面跟類的具體詳細(xì)例子,、public class DB2_JDBCFactory {private static DB2_JDBCFactory instance = null; public static final ThreadLocal threadLocal = new ThreadLocal(); private DB2_JDBCFactory() {
} public static DB2_JDBCFactory getInstance() {
if(instance == null) {
synchronized(DB2_JDBCFactory.class) { //synchronized后面跟一個(gè)類
instance = new DB2_JDBCFactory();
}
}
return instance;
} public Connection getConnection_JNDI_localhost(){
Connection c = (Connection) threadLocal.get();
try {
if (c == null || c.isClosed()) {
InitialContext ctx = new InitialContext();
DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/localhost");
c = ds.getConnection();
threadLocal.set(c);
}
} catch (Exception ex) {
System.err.println("getConnection_JNDI Initial failed. " + ex);
return null;
}
return c;
}}外面的對(duì)象訪問這個(gè)類的 需要通過調(diào)用它的getInstance()

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn),。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多