一、每个线程执行的代码相同:
若每个线程执行的代码相同,共享数据就比较方便。可以使用同一个Runnable对象,这个Runnable对象中就有那个共享数据。
1 public class MultiThreadShareData 2 { 3 public static void main(String[] args) 4 { 5 SaleTickets sale = new SaleTickets(); 6 new Thread(sale).start(); 7 new Thread(sale).start(); 8 } 9 } 10 class SaleTickets implements Runnable 11 { 12 public int allTicketCount = 20; 13 public void run() 14 { 15 while (allTicketCount > 0) 16 { 17 sale(); 18 } 19 } 20 public synchronized void sale() 21 { 22 System.out.println("剩下" + allTicketCount); 23 allTicketCount--; 24 } 25 }
SaleTickets这个对象中就有需要共享的数据allTicketCount,两个线程使用同一个SaleTickets,就可以共享allTicketCount了。
二、每个线程执行的代码不相同:
方法1:将需要共享的数据封装成一个对象,将该对象传给执行不同代码的Runnable对象。
方法2:将这些执行不同代码的Runnable对象作为内部类。
看例子:有4个线程,其中有2个线程对每次对j +1,有2个线程对每次对j -1。加减操作无顺序。
(1)方法1:
1 public class MultiThreadShareData3 2 { 3 public static void main(String[] args) 4 { 5 int j = 10; 6 NumberInfo nInfo = new NumberInfo(j); 7 for (int i = 0; i < 2; i++) 8 { 9 new Thread(new NumberInfoAdd("增线程", nInfo)).start(); 10 new Thread(new NumberInfoMinus("减线程", nInfo)).start(); 11 } 12 } 13 } 14 15 class NumberInfo 16 { 17 private int number; 18 public NumberInfo(int number) 19 { 20 this.number = number; 21 } 22 public int getNumber() 23 { 24 return number; 25 } 26 public void setNumber(int number) 27 { 28 this.number = number; 29 } 30 public void add() 31 { 32 System.out.println("数值:" + (++number)); 33 } 34 public void minus() 35 { 36 System.out.println("数值:" + (--number)); 37 } 38 } 39 40 // 增操作 41 class NumberInfoAdd implements Runnable 42 { 43 private String name; 44 private NumberInfo nInfo; 45 public NumberInfoAdd(String name, NumberInfo nInfo) 46 { 47 this.name = name; 48 this.nInfo = nInfo; 49 } 50 public void run() 51 { 52 add(); 53 } 54 public void add() 55 { 56 synchronized (nInfo) 57 { 58 System.out.print(name + "--"); 59 nInfo.add(); 60 } 61 } 62 } 63 64 // 减操作 65 class NumberInfoMinus implements Runnable 66 { 67 private String name; 68 private NumberInfo nInfo; 69 public NumberInfoMinus(String name, NumberInfo nInfo) 70 { 71 this.name = name; 72 this.nInfo = nInfo; 73 } 74 public void run() 75 { 76 minus(); 77 } 78 public void minus() 79 { 80 synchronized (nInfo) 81 { 82 System.out.print(name + "--"); 83 nInfo.minus(); 84 } 85 } 86 }
(2)方法2:
1 public class MultiThreadShareData4 2 { 3 int j = 10; 4 public static void main(String[] args) 5 { 6 MultiThreadShareData4 m = new MultiThreadShareData4(); 7 for (int i = 0; i < 2; i++) 8 { 9 new Thread(m.new NumberInfoAdd()).start(); 10 new Thread(m.new NumberInfoMinus()).start(); 11 } 12 } 13 public synchronized void add() 14 { 15 System.out.println("增加后数值:" + (++j)); 16 } 17 public synchronized void minus() 18 { 19 System.out.println("減少后数值:" + (--j)); 20 } 21 22 // 增 23 class NumberInfoAdd implements Runnable 24 { 25 public void run() 26 { 27 add(); 28 } 29 } 30 31 // 减 32 class NumberInfoMinus implements Runnable 33 { 34 public void run() 35 { 36 minus(); 37 } 38 } 39 }
执行结果可能是:
增线程--数值:11
增线程--数值:12
减线程--数值:11
减线程--数值:10
执行结果也可能是:
增线程--数值:11
减线程--数值:10
减线程--数值:9
增线程--数值:10
三、其实线程执行相同代码也可以按照这些方法来做,看一个方法1:
1 public class MultiThreadShareData2 2 { 3 public static void main(String[] args) 4 { 5 TicketInfo tInfo = new TicketInfo(20); 6 new Thread(new SaleTickets2("线程1", tInfo)).start(); 7 new Thread(new SaleTickets2("线程2", tInfo)).start(); 8 } 9 } 10 class TicketInfo 11 { 12 private int allTicketCount; 13 public TicketInfo(int allTicketCount) 14 { 15 this.allTicketCount = allTicketCount; 16 } 17 public int getAllTicketCount() 18 { 19 return allTicketCount; 20 } 21 public void setAllTicketCount(int allTicketCount) 22 { 23 this.allTicketCount = allTicketCount; 24 } 25 public void sale() 26 { 27 System.out.println("剩余:" + allTicketCount--); 28 } 29 } 30 class SaleTickets2 implements Runnable 31 { 32 private String name; 33 private TicketInfo tInfo; 34 public SaleTickets2(String name, TicketInfo tInfo) 35 { 36 this.name = name; 37 this.tInfo = tInfo; 38 } 39 public void run() 40 { 41 while (tInfo.getAllTicketCount() > 0) 42 { 43 sale(); 44 } 45 } 46 public void sale() 47 { 48 synchronized (tInfo) 49 { 50 System.out.print(name + "--"); 51 tInfo.sale(); 52 } 53 } 54 }