1.沒有多線程環境就不需要同步。
2.即使有多線程環境也不一定需要同步。
爲了防止多個線程對同一數據的修改,所以需要同步,否則會造成數據不一致。
Java提供了非常方便的多線程支持,所以說同步問題比較普遍,尤其是Servlet和
JSP的線程安全問題特別明顯。
http://blog.csdn.net/treeroot/archive/2004/09/03/93881.aspx
Java同步其實就是獲得對象的同步鎖,其他線程就只能等待。我們的大部分程序都
只舉一個例子說明同步的實質。
class SynTest{
synchronized static method(){
//這個方法是同步的方法,每次只有一個線程可以進來
System.out.println("begin");
try{Thread.sleep(2000);}
System.out.println("end");
}
public static void main(String[] args){
//啓動10個線程,這裏用了匿名類,因爲確實方便不少。
for(int i=0;i<10;i++){
new Thread(){
public void run(){
method();
}
}.start();
}
}
}
很容易看到每個線程必須等待前一個線程退出方法method後纔可以進去。
上面的同步方法可以有另外的兩種等價方式:
class SynTest{
static method(){
synchronized(SynTest.class){
//這個方法雖然不是同步的方法,但是每次只有一個線程可以進到同步塊
System.out.println("begin");
try{Thread.sleep(2000);}
System.out.println("end");
}
}
public static void main(String[] args){
//啓動10個線程,這裏用了匿名類,因爲確實方便不少。
for(int i=0;i<10;i++){
new Thread(){
public void run(){
method();
}
}.start();
}
}
}
class SynTest{
private static Object lock=new Object();
static method(){
synchronized(lock){
//這個方法用一個專門的對象作爲鎖。
System.out.println("begin");
try{Thread.sleep(2000);}
System.out.println("end");
}
}
public static void main(String[] args){
//啓動10個線程,這裏用了匿名類,因爲確實方便不少。
for(int i=0;i<10;i++){
new Thread(){
public void run(){
method();
}
}.start();
}
}
}
這裏先說明一點,同步和是否線程安全和方法是否是靜態的一點關係都沒有。
假設一個類沒有提供直接修改成員變量的操作,也就是算只能通過方法修改
對象。我們很容易得出結論,只有所有的方法是線程安全的,這個類纔是線程
安全的。那麼如何判斷一個方法是否線程安全的,只有看說明文檔或者閱讀源碼了
class Math{
public static int safePow(int x,int y){//假設y大於0
int res=x;
for(int i=1;i<y;i++) res*=x;
return res;
}
public static int unsafePow(int x,int y){
pow=y;
return pow(x);
}
private static int pow;
private static int pow(int x){
int res=x;
for(int i=1;i<pow;i++) res*=x;
return res;
}
}
我都不知道怎麼回舉這麼無聊的例子,而且我發現這個問題腦子裏很清楚,卻很難
Thread1: unsafePow(3,3);
Thread2: unsafePow(2,2);
假設Thread1執行到 pow=y;進入方法pow(int x);
此時pow=3;
然後Thread2執行pow=y; 進入方法pow(int x);
此時pow=2;
然後線程1執行pow(int x)方法應該等到的是3的2次方,導致錯誤,所以說
這個方法不是線程安全的。
一樣的),而且對於訪問方法同樣存在線程安全問題。
我們知道Hashtable是線程安全的,因爲所有的方法都同步了,也就是說最多隻能同
那就有可能你調用size方法還沒有返回,一個線程又添加了一個數據,這個時候你讀取到的值應該是正確
public class SynHashtable{
public static void main(String[] args)
{
final Hashtable ht=new Hashtable();
ht.put(new Object(),"Quick to Death");
new Thread(){
public void run(){
while(true){
if(ht.size()<10){
ht.put(new
}
else{
ht.clear();
}
}
}
}.start();
new Thread(){
public void run(){
unsafe(ht);
}
}.start();
}
while(true){
//synchronized(ht){
Iterator it=ht.values().iterator();
while(it.hasNext())
System.out.println(it.next());
}
//}
}
}
如果不同步的話很快就會崩潰。