多線程范圍內的共享解決方法參考有4中:
1.如果線程執行的代碼相同,多個線程共享同一個runnable對象時,將共享數據放在runnable對象
2.如果多個線程執行的代碼不同,將共享數據封裝到一個對象中,將這個對象逐一傳遞給各個runnable對象
3.如果多個線程執行的代碼不同,將共享數據作為外部類的final成員變量,將不同的runnable對象作為內部類主動取數據
4.將數據聲明為static的方式()
見如下示例:
1.如果線程執行的代碼相同,多個線程共享同一個runnable對象時,將共享數據放在runnable對象
public class MuiltThreadShare { /** * 多個線程共享數據方法: * 1.如果線程執行的代碼相同,多個線程共享同一個runnable對象時,將共享數據放在runnable對象 * 2.如果多個線程執行的代碼不同,將共享數據封裝到一個對象中,將這個對象逐一傳遞給各個runnable對象 * 3.如果多個線程執行的代碼不同,將共享數據作為外部類的final成員變量,將不同的runnable對象作為內部類主動取數據 */ public static void main(String[] args) { //1.方式一 Task1 task1 = new Task1(); new Thread(task1).start(); new Thread(task1).start(); new Thread(task1).start(); } } class Task1 implements Runnable{ /** * 1.如果線程執行的代碼相同,多個線程共享同一個runnable對象時,將共享數據放在runnable對象 */ private int i = 100; @Override public void run() { increase(); decrease(); } private synchronized void increase(){ try { Thread.sleep(200);//為了更容易看到線程執行現象 } catch (InterruptedException e) { e.printStackTrace(); } i++; System.out.println(Thread.currentThread().getName() +",num:"+i); } private synchronized void decrease(){ i--; System.out.println(Thread.currentThread().getName() +",num:"+i); }
運行結果:最終還是100,不同的線程使用共享數據
運行結果 // Thread-0,num:101 // Thread-2,num:102 // Thread-1,num:103 // Thread-2,num:102 // Thread-0,num:101 // Thread-1,num:100
2.如果多個線程執行的代碼不同,將共享數據封裝到一個對象中,將這個對象逐一傳遞給各個runnable對象
public class MuiltThreadDataShare2 { public static void main(String[] args) { // 2.如果多個線程執行的代碼不同,將共享數據封裝到一個對象中,將這個對象逐一傳遞給各個runnable對象 /** * 模擬銀行轉賬功能,可以指定存取款金額,賬號初始額度100 */ ShareData data = new ShareData(0); // 存50元 new Thread(new TaskIncrease(data, 50)).start(); // 取30元 new Thread(new Taskdecrease(data, 30)).start(); // 存20 new Thread(new TaskIncrease(data, 20)).start(); } } class Taskdecrease implements Runnable { public Taskdecrease(ShareData shareData, int num) { this.shareData = shareData; this.num = num; } private int num; private ShareData shareData; @Override public void run() { shareData.decrease(num); } } class TaskIncrease implements Runnable { public TaskIncrease(ShareData shareData, int num) { this.shareData = shareData; this.num = num; } private ShareData shareData; private int num; @Override public void run() { shareData.increase(num); } } class ShareData { public ShareData(int num) { i = num; System.out.println("賬戶進行初始化,金額為:" + num); } private int i; public synchronized void increase(int i) { try { Thread.sleep(200);// 為了更容易看到線程執行現象 } catch (InterruptedException e) { e.printStackTrace(); } this.i = this.i + i; System.out.println(Thread.currentThread().getName() + "賬戶存入" + i + "元,目前賬戶余額為:" + this.i); } public synchronized void decrease(int i) { this.i = this.i - i; System.out.println(Thread.currentThread().getName() + "賬戶取出" + i + "元,目前賬戶余額為:" + this.i); } }
運行結果:
賬戶進行初始化,金額為:0 Thread-0賬戶存入50元,目前賬戶余額為:50 Thread-2賬戶存入20元,目前賬戶余額為:70 Thread-1賬戶取出30元,目前賬戶余額為:40
3.如果多個線程執行的代碼不同,將共享數據作為外部類的final成員變量,將不同的runnable對象作為內部類主動取數據
public class MuiltThreadDataShare3 { public static void main(String[] args) { final Data data = new Data(); new Thread(new Runnable() { @Override public void run() { data.decrease(10); } }).start(); new Thread(new Runnable() { @Override public void run() { data.increase(30); } }).start(); } } class Data { private int money = 100; public int getMoney() { return money; } public void setMoney(int money) { this.money = money; } public synchronized void increase(int i) { try { Thread.sleep(200);// 為了更容易看到線程執行現象 } catch (InterruptedException e) { e.printStackTrace(); } this.money = this.money + i; System.out.println(Thread.currentThread().getName() + "賬戶存入" + i + "元,目前賬戶余額為:" + this.money); } public synchronized void decrease(int i) { this.money = this.money - i; System.out.println(Thread.currentThread().getName() + "賬戶取出" + i + "元,目前賬戶余額為:" + this.money); } }
4.將數據聲明為static的方式
public class MuiltThreadDataShare4 { private static int num = 100; public static void main(String[] args) { new Thread(new Runnable() { @Override public void run() { increase(100); } }).start(); new Thread(new Runnable() { @Override public void run() { decrease(30); } }).start(); } public static synchronized void increase(int i) { try { Thread.sleep(200);// 為了更容易看到線程執行現象 } catch (InterruptedException e) { e.printStackTrace(); } num = num + i; System.out.println(Thread.currentThread().getName() + "賬戶存入" + i + "元,目前賬戶余額為:" + num); } public static synchronized void decrease(int i) { num = num - i; System.out.println(Thread.currentThread().getName() + "賬戶取出" + i + "元,目前賬戶余額為:" + num); } }
完