JWorld@TW the best professional Java site in Taiwan
      註冊 | 登入 | 全文檢索 | 排行榜  

» JWorld@TW » Java SE 討論區 » Threads/Synchronization  

按列印兼容模式列印這個話題 列印話題    把這個話題寄給朋友 寄給朋友   
reply to topicthreaded modego to previous topicgo to next topic
本主題所含的標籤
無標籤
作者 如何讓method之間無法平行進行, 但是....
easylin





發文: 8
積分: 0
於 2007-09-29 16:54 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
假設我有
class MyClass {
void method1(Key k) {
....
}
void method2(Key k) {
....
}
void method3(Key k) {
...
}
}

method1~3會同時被很多thread執行, Key值幾乎無法預期

method本身可以同時被執行(e.g. method1可以同時被很多thread執行)

但在相同Key時 method1 method2 method3 不可以同時進行
(e.g. method1(key1), method2(key1), method3(key1) 不可以同時進行
但method1(key1) 本身還是可以同時被很多thread同時呼叫....)

請問有什麼點子嗎
(不需要太複雜的lock技巧....XD)


reply to postreply to post
作者 Re:如何讓method之間無法平行進行, 但是.... [Re:easylin]
Duncan

還隱隱作痛

版主

發文: 7816
積分: 39
於 2007-09-29 18:47 user profilesend a private message to usersend email to Duncanreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
easylin wrote:
假設我有
class MyClass {
void method1(Key k) {
....
}
void method2(Key k) {
....
}
void method3(Key k) {
...
}
}

method1~3會同時被很多thread執行, Key值幾乎無法預期

method本身可以同時被執行(e.g. method1可以同時被很多thread執行)

但在相同Key時 method1 method2 method3 不可以同時進行
(e.g. method1(key1), method2(key1), method3(key1) 不可以同時進行
但method1(key1) 本身還是可以同時被很多thread同時呼叫....)

請問有什麼點子嗎
(不需要太複雜的lock技巧....XD)


確認一下意思,multi-thread 同時 pass 相同的 actual argument 給 method1 來並行運行是允許的嗎?


Duncan edited on 2007-09-29 18:49
reply to postreply to post

給我
辣味豆腐 其餘免談
作者 Re:如何讓method之間無法平行進行, 但是.... [Re:easylin]
easylin





發文: 8
積分: 0
於 2007-09-29 20:48 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
嗯 key 只在意semantic 的意思

Long k1 = new Long(123);
long k2 = 123;

method1(k1) 和 method1(k2) 是同樣的意義 Sad


reply to postreply to post
作者 Re:如何讓method之間無法平行進行, 但是.... [Re:easylin]
hkdennis2k





發文: 1926
積分: 6
於 2007-09-29 23:33 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
確認一下

Cast1:
Thread1->method1("x"); 可
Thread2->method1("x"); 可
Thread3->method1("x"); 可

Cast2:
Thread1->method1("x"); 可
Thread2->method1("y"); 可
Thread3->method1("z"); 可

Cast3:
Thread1->method1("x"); 不可
Thread2->method2("x"); 不可
Thread3->method3("x"); 不可

Cast4:
Thread1->method1("x"); 可
Thread2->method2("y"); 可
Thread3->method3("z"); 可

是這樣嗎?

key 會是 singleton 嗎? (不會 a!=b && a.equals(b) )
如果否, 能否從 key 本身算出一樣特定值的方法呢?


hkdennis2k edited on 2007-09-29 23:37
reply to postreply to post
1. Programming is not coding

2. Learning Java is not leaning Java syntax

3. Study, not wait for be taught

4. Answer to yourself, not ask somebody else

5. Code is poetry

---
6. 我跑去寫 C# 了....

---
7. 回到 Java, PHP 還有 servers farm
---
8. 很久沒有寫 Java 了, 倒
作者 Re:如何讓method之間無法平行進行, 但是.... [Re:hkdennis2k]
easylin





發文: 8
積分: 0
於 2007-09-30 01:14 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
hkdennis2k wrote:
確認一下

Cast1:
Thread1->method1("x"); 可
Thread2->method1("x"); 可
Thread3->method1("x"); 可

Cast2:
Thread1->method1("x"); 可
Thread2->method1("y"); 可
Thread3->method1("z"); 可

Cast3:
Thread1->method1("x"); 不可
Thread2->method2("x"); 不可
Thread3->method3("x"); 不可

Cast4:
Thread1->method1("x"); 可
Thread2->method2("y"); 可
Thread3->method3("z"); 可

是這樣嗎?

key 會是 singleton 嗎? (不會 a!=b && a.equalsBeer )
如果否, 能否從 key 本身算出一樣特定值的方法呢?

沒錯 case都對~~ :-p

key 不會是singleton Sad


reply to postreply to post
作者 Re:如何讓method之間無法平行進行, 但是.... [Re:easylin]
kentyeh





發文: 648
積分: 6
於 2007-09-30 08:51 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
Cast1:
Thread1->method1("x"); 可
Thread2->method1("x"); 可
Thread3->method1("x"); 可

假設的狀況有點不明白,能不能說明一下為什麼不同的thread不可以使用相同的KEY執行不同的method?可是確允許不同的thread可以使用相同的KEY執行相同的method?


reply to postreply to post
作者 Re:如何讓method之間無法平行進行, 但是.... [Re:easylin]
hkdennis2k





發文: 1926
積分: 6
於 2007-09-30 10:07 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
這樣的話, 的確是很麻煩.....

大既要這樣寫吧?

ConcurrentHashMap map;

method1(key){
Object lock=new Object[]{
new Object(),
new Object(),
new Object()
};
Object lock2=map.putIfAbsent(key,lock);
if(lock2!=null) lock=lock2;
synchronized(lock[1]){
synchronized(lock[2]){
/////// logic here
}
}
}

method2(key){
略..........
synchronized(lock2[0]){
synchronized(lock2[2]){
略..........
}

method3(key){
略..........
synchronized(lock2[0]){
synchronized(lock2[1]){
略..........
}

沒試過, 不過最簡單的方法大約是這樣吧!?
而且就是可見的 memory leak (沒有在 map remove 任何 key)

不過如果要求不太高的話, 可放棄 cast1 會比較簡單一點


reply to postreply to post
1. Programming is not coding

2. Learning Java is not leaning Java syntax

3. Study, not wait for be taught

4. Answer to yourself, not ask somebody else

5. Code is poetry

---
6. 我跑去寫 C# 了....

---
7. 回到 Java, PHP 還有 servers farm
---
8. 很久沒有寫 Java 了, 倒
作者 Re:如何讓method之間無法平行進行, 但是.... [Re:hkdennis2k]
plutotw

井底蛙



發文: 624
積分: 3
於 2007-09-30 10:46 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Hashtable keysHash[]= new Hashtable[]{new Hashtable[],new Hashtable[],new Hashtable[] } ;
Object synchronizedKey = new Object() ;
synchronized  private boolean isSynchronized( int index , Object key ) {
  synchronized  ( synchronizedKey) {
  // TODO 
  //檢查 keysHash[index] 的 key  是否存在, 存在 return TRUE ( ++count) ; 
  // 檢查 非  keysHash[index] 的 key  是否存在,存在 return FALSE ; 
 
    keysHash[index] add  key  : set count =1 
  }
  return TRUE ;
}
 
 private void removeSynchronized( int index , Object key ) {
  synchronized  ( synchronizedKey) {
    // if ( --count == 0 )     keysHash[ ? ] remove key ;
  }
}
public void method?( Object key )  {
  if (! isSynchronized( ? , key ) ) 
     return ;
 
// TODO
//該做的事
 
removeSynchronized( ? , key ) ; 
}
}


plutotw edited on 2007-09-30 16:24
reply to postreply to post
作者 Re:如何讓method之間無法平行進行, 但是.... [Re:plutotw]
hkdennis2k





發文: 1926
積分: 6
於 2007-09-30 12:29 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
plutotw wrote:
1
2
3
4
5
6
.........
  synchronized  ( synchronizedKey) {
     keysHash[ ? ] remove key ;
  }
}
}



這樣會出現問題
1.
在 case 1, 同時執行 same key, same method時
會發生 thread 未完成郤 remove key 的情況,

2.
會出現 non-fair 情況

所以我才沒有加上 remove, 而說有 memory leak 的問題

細心的話其實也可以用 Thread.currentThread() 和 Set 的組合避免 memory leak


reply to postreply to post
1. Programming is not coding

2. Learning Java is not leaning Java syntax

3. Study, not wait for be taught

4. Answer to yourself, not ask somebody else

5. Code is poetry

---
6. 我跑去寫 C# 了....

---
7. 回到 Java, PHP 還有 servers farm
---
8. 很久沒有寫 Java 了, 倒
作者 Re:如何讓method之間無法平行進行, 但是.... [Re:hkdennis2k]
plutotw

井底蛙



發文: 624
積分: 3
於 2007-09-30 16:05 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
hkdennis2k wrote:
1.
在 case 1, 同時執行 same key, same method時
會發生 thread 未完成郤 remove key 的情況,

已修正上篇

2.
會出現 non-fair 情況

不懂,請說明

所以我才沒有加上 remove, 而說有 memory leak 的問題

在 method1() 內的
synchronized(lock[1]){
synchronized(lock[2]){ // TODO }}
這兩個 method1() 的 local 內的 又如何能與 method2() , method3() 搭配
如 method2() {
synchronized(lock[0]){
synchronized(lock[2]){ // TODO }}
但在 lock[0] 是誰 lock 的, method1() 內 沒有, 而 method1() 內也不能用 lock ,否則其他 Thread 就不會正常繼續
反正我看的很暈,能否用中文註解


plutotw edited on 2007-09-30 16:23
reply to postreply to post
作者 Re:如何讓method之間無法平行進行, 但是.... [Re:plutotw]
easylin





發文: 8
積分: 0
於 2007-09-30 16:38 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
plutotw wrote:
1
2
3
4
5
6
7
8
9
10
11
12
synchronized  private boolean isSynchronized( int index , Object key ) {
  synchronized  ( synchronizedKey) {
  ...
  }
  return TRUE ;
}
 
 private void removeSynchronized( int index , Object key ) {
  synchronized  ( synchronizedKey) {
   ...
  }
}


問個概念
1
2
3
4
  synchronized  ( synchronizedKey) {
  ...
  }
  

會互相影響嗎?
對於相同object的synchronized, 在不同的scope, 會也互相block嗎?


reply to postreply to post
作者 Re:如何讓method之間無法平行進行, 但是.... [Re:plutotw]
hkdennis2k





發文: 1926
積分: 6
於 2007-10-01 01:06 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
non-fair
簡單來個例子
三條 thread 利用相同的 key
thread1 連續執行 method1
thread2 連續執行 method2
thread3 連續執行 method3

以 plutotw 的寫法, 則有可能出現
thread1 能連續成功執行十次, 百次, 甚至千次
而 thread2 和 thread3 則完全不能執行的情況

---

synchronized 是只針對 object instance 而不是其他任何事物


reply to postreply to post
1. Programming is not coding

2. Learning Java is not leaning Java syntax

3. Study, not wait for be taught

4. Answer to yourself, not ask somebody else

5. Code is poetry

---
6. 我跑去寫 C# 了....

---
7. 回到 Java, PHP 還有 servers farm
---
8. 很久沒有寫 Java 了, 倒
作者 Re:如何讓method之間無法平行進行, 但是.... [Re:easylin]
hkdennis2k





發文: 1926
積分: 6
於 2007-10-01 01:27 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
我之前那個做法好像是錯了的呢
它能滿足 case 3 而不能滿足 case 1


reply to postreply to post
1. Programming is not coding

2. Learning Java is not leaning Java syntax

3. Study, not wait for be taught

4. Answer to yourself, not ask somebody else

5. Code is poetry

---
6. 我跑去寫 C# 了....

---
7. 回到 Java, PHP 還有 servers farm
---
8. 很久沒有寫 Java 了, 倒
作者 Re:如何讓method之間無法平行進行, 但是.... [Re:hkdennis2k]
easylin





發文: 8
積分: 0
於 2007-10-01 01:42 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
後來我嚐試用ReadWriteLock...
不過不知道怎麼測Tread programming...


reply to postreply to post
作者 Re:如何讓method之間無法平行進行, 但是.... [Re:hkdennis2k]
plutotw

井底蛙



發文: 624
積分: 3
於 2007-10-01 08:38 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
hkdennis2k wrote:
以 plutotw 的寫法, 則有可能出現
thread1 能連續成功執行十次, 百次, 甚至千次
而 thread2 和 thread3 則完全不能執行的情況

請舉例錯誤的地方
原設計是在同一個 key0 之下 thread1 一直執行,當然同一 key0 -> thread2,tread3 根本不能執行 ,但 thread2,tread3 可執行其他 key2
反之 thread1 一但全部執行完成, thread2 或 tread3 則隨時用同一 key0 可取代 thread1


reply to postreply to post
» JWorld@TW »  Java SE 討論區 » Threads/Synchronization

reply to topicthreaded modego to previous topicgo to next topic
  已讀文章
  新的文章
  被刪除的文章
Jump to the top of page

JWorld@TW 本站商標資訊

Powered by Powerful JuteForum® Version Jute 1.5.8