多線程間變量的共享

寫python程序的時候遇到了共享變量的問題,在網上看到了一篇講java多線程變量共享的文章,有共通之處,整理下發在這裏吧。

1.方法體內部定義的局部變量不共享。

這是因爲方法內部定義的變量是在運行時動態生成的。每個線程都有一個自己的堆棧,用於保存運行時的數據。 最容易理解的就是遞歸調用時候,每次的入棧出棧操作。如下,每次調用時,變量a都是在運行時堆棧上保存的,方法結束變量也就釋放了。

public int fib(int n)
{
    int a;
    if(n==1 || n==0)
        return 1;
    else
        return fib(n-1)*n;
}

2.成員變量需要看變量指向的是否爲同一個對象。

看下面的代碼示例:

public class Analy {
    public static void main(String[] args) {
        Num i=new Num(0);    //新建對象,準備傳遞給線程,對於對象java採用引用傳遞,因此線程間相當於共享該變量
        OwnThread t1=new OwnThread(i);    
        OwnThread t2=new OwnThread(i);    //新建線程,並啓動
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println("主線程中i的值變爲了:"+i.i);    //獲取目前對象i的數值
    }
}
class OwnThread extends Thread
{
    Num id;    //申明對象,默認null,就是沒有指向任何實體
    int sno;    //申明int變量。因爲系統默認初始化爲0,所以應該是定義一個int變量
    OwnThread(Num id)
    {
        this.id=id;
    }    
    public void run()
    { 
        for(int i=0;i<5;i++)
        {
            synchronized(this)
            {
                sno=id.i;    //保存id.i的數值,到線程私有變量sno
                id.i++;
                try {
                    Thread.sleep(1);
                } 
                catch (InterruptedException e) {}
            }
            System.out.println(this.getName()+","+sno);
        }
    }
}
class Num    //定義一個類
{
    int i;
    Num(int i)
    {
        this.i=i;
    }
}

運行結果:

Thread-1,1
Thread-0,0
Thread-1,2
Thread-0,3
Thread-1,4
Thread-0,5
Thread-0,7
Thread-1,6
Thread-0,8
Thread-1,9
主線程中i的值變爲了:10

分析:

程序中主函數定義了Num對象的實例i,傳遞到了Thread0和Thread1。這樣線程間就共享了一個Num對象的實例。而線程Thread0和線程Thread1又有自己的私有變量sno,可以用來保存某一時刻的共享變量的數值。


Java中判斷對象是否爲同一個對象使用地址判斷的。地址相同就是同一個對象,上面的三個就是同一個對象。
如果把上面的例子中共享的對象實例用基本數據類型替換是不行的。因爲基本數據類型程序會自動的用默認值初始化,也就是申明和定義時一起的。此時在mian函數中定義線程,傳遞的基本數據類型參數,只能是初始化線程中的另一個對象,而不是同一個對象。

總結:

總之,在多線程編程中,知道各個線程如何、怎麼樣共享數據是很重要的。
如上面的程序,可以在主線程和其他兩個子線程之間共享一個對象,來實現他們之間的交互處理。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章