出問題了,共享變量
我們先來看一段代碼
public class Main {
public static void main(String[] args) throws InterruptedException {
TheThread theThread1=new TheThread();
TheThread theThread2=new TheThread();
theThread1.start();
theThread2.start();
}
static int i = 0;
public static class TheThread extends Thread{
public void run(){
for(;i<100;){
i++;
System.out.println(Thread.currentThread().getId()+":"+i);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
這個運(yùn)行的最終結(jié)果本來應(yīng)該是200粒梦,但是結(jié)果遠(yuǎn)遠(yuǎn)小于200,如果循環(huán)次數(shù)越多荸实,則結(jié)果差距越大匀们,這是為什么呢?
當(dāng)一個線程區(qū)訪問這個變量的時候泪勒,另外的線程也可以訪問昼蛀,在修改值得時候,存在同時修改的可能性圆存,這時候i只能被賦值一次叼旋,這就導(dǎo)致了一個問題。這個問題我們叫做線程安全問題沦辙。這個變量我們稱作共享變量夫植。
解決問題:同步
并發(fā)中,共享變量會導(dǎo)致的一個問題就是線程安全問題,為了解決這個問題详民,我們要做的就是控制線程訪問延欠。在一個線程在訪問的這個共享資源的時候,其他線程無法訪問沈跨,這就是同步由捎。
Java為了解決同步問題,專門設(shè)置了關(guān)鍵字饿凛,叫synchronized狞玛,我們來寫一個線程安全的代碼:
public class Main {
public static void main(String[] args) throws InterruptedException {
int i=0;
ObjA o=new ObjA(i);
TheThread theThread1=new TheThread(o);
TheThread theThread2=new TheThread(o);
theThread1.start();
theThread2.start();
}
}
class TheThread extends Thread {
private ObjA objA;
public TheThread(ObjA objA) {
this.objA=objA;
}
public void run() {
objA.method();
}
}
class ObjA{
int i;
public ObjA(int i) {
this.i=i;
}
synchronized public void method() {
for(int j=0;j<50;j++) {
i++;
System.out.println(i);
}
}
}