一、每个线程执行的代码相同:
若每个线程执行的代码相同,共享数据就比较方便。可以使用同一个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 Runnable11 {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 NumberInfo16 {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 Runnable42 {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 Runnable66 {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 Runnable24 {25 public void run()26 {27 add();28 }29 }30 31 // 减32 class NumberInfoMinus implements Runnable33 {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 TicketInfo11 {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 Runnable31 {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 }