變數共用,是看線程的建立方式
package sample1;public class ShareVariable { public static void main(String[] args) { System.out.println(Thread.currentThread().getName()); // 資料不共用 // MyThreadForV a = new MyThreadForV("A"); // MyThreadForV b = new MyThreadForV("B"); // MyThreadForV c = new MyThreadForV("C"); // a.start(); // b.start(); // c.start(); // 資料共用:extends Thread // MyThreadForV t = new MyThreadForV(); // Thread a = new Thread(t, "A"); // Thread b = new Thread(t, "B"); // Thread c = new Thread(t, "C"); // Thread d = new Thread(t, "D"); // Thread e = new Thread(t, "E"); // Thread f = new Thread(t, "F"); // a.start(); // b.start(); // c.start(); // d.start(); // e.start(); // f.start(); // 資料不共用:implement Runnable MyRunnableForV r1 = new MyRunnableForV(); MyRunnableForV r2 = new MyRunnableForV();// MyRunnableForV r3 = new MyRunnableForV();// MyRunnableForV r4 = new MyRunnableForV();// r1.run();// r2.run();// r3.run();// r4.run(); // 資料共用:implement Runnable Thread a = new Thread(r1, "A"); Thread b = new Thread(r1, "B"); a.start(); b.start(); }}class MyThreadForV extends Thread { private int count = 5; public MyThreadForV() { } public MyThreadForV(String name) { this.setName(name); } @Override public void run() { while (count > 0) { count--; System.out.println("由" + currentThread().getName() + "計算, count=" + count); } }}class MyRunnableForV implements Runnable { private int count = 5; public void setCount(int num) { this.count = num; } public MyRunnableForV() { } @Override public void run() { // super.run(); while (count > 0) { count--; System.out.println(" count=" + count); } }}
繼承Thread還是實現Runnable 都是可以共用成員變數的,要看執行個體化的時候是不是用的new Thread(t1),new Thread(t2)
而如果使用共用變數的話,上面的線程方法是不安全的,可以在public void run(){}前面加上synchronized(同步鎖)。因為jvm在進行多線程操作時,對變數的操作 i– 是:
1、讀取原有i,
2、計算i–,
3、重新賦值i。
如果不加同步鎖的話,多個線程可能會相互影響。
比如:t1進行到第二步,t2開始進行第一步。這樣必定出問題。而加了鎖後,t1開始,則i被加鎖。t2必須等到t1結束才能開始第一步。
synchronized鎖可對任意對象和方法。
java裡不能直接使用synchronized聲明一個變數,而是使用synchronized去修飾一個代碼塊或一個方法。
詳細說明如下:
synchronized用來修飾一個方法或者一個代碼塊,它用來保證在同一時刻最多隻有一個線程執行該段代碼。
一、當兩個並發線程訪問同一個對象object中的這個synchronized(this)同步代碼塊時,一個時間內只能有一個線程得到執行。另一個線程必須等待當前線程執行完這個代碼塊以後才能執行該代碼塊。
二、然而,當一個線程訪問object的一個synchronized(this)同步代碼塊時,另一個線程仍然可以訪問該object中的非synchronized(this)同步代碼塊。
三、尤其關鍵的是,當一個線程訪問object的一個synchronized(this)同步代碼塊時,其他線程對object中所有其它synchronized(this)同步代碼塊的訪問將被阻塞。
四、第三個例子同樣適用其它同步代碼塊。也就是說,當一個線程訪問object的一個synchronized(this)同步代碼塊時,它就獲得了這個object的對象鎖。結果,其它線程對該object對象所有同步代碼部分的訪問都被暫時阻塞。
五、以上規則對其它對象鎖同樣適用