一、每个线程执行的代码相同

若每个线程执行的代码相同,共享数据就比较方便。可以使用同一个Runnable对象,这个Runnable对象中就有那个共享数据。

public class MultiThreadShareData1
{
public static void main(String[] args)
{
 SaleTickets sale = new SaleTickets();
 new Thread(sale).start();
 new Thread(sale).start();
}
}

class SaleTickets implements Runnable
{
public int allTicketCount = 20;

public void run()
{
 while (allTicketCount > 0)
 {
  sale();
 }
}

public synchronized void sale()
{
 System.out.println("
剩下" + allTicketCount);
 allTicketCount--;
}
}
SaleTickets这个对象中就有需要共享的数据allTicketCount,两个线程使用同一个SaleTickets,就可以共享allTicketCount了。


二、每个线程执行的代码不相同
方法1:将需要共享的数据封装成一个对象,将该对象传给执行不同代码的Runnable对象。
方法2:将这些执行不同代码的Runnable对象作为内部类。
看例子:有4个线程,其中有2个线程对每次对j+1,有2个线程对每次对j-1。加减操作无顺序。

方法1:
public class MultiThreadShareData3
{
public static void main(String[] args)
{
int j = 10;
NumberInfo nInfo = new NumberInfo(j);
 for (int i = 0; i < 2; i++)
 {
  new Thread(new NumberInfoAdd("增线程", nInfo)).start();
  new Thread(new NumberInfoMinus("减线程", nInfo)).start();
 }
}
}

class NumberInfo
{
private int number;

public NumberInfo(int number)
{
 this.number = number;
}

public int getNumber()
{
 return number;
}

public void setNumber(int number)
{
 this.number = number;
}

public void add()
{
 System.out.println("
数值:" + (++number));
}

public void minus()
{
 System.out.println("
数值:" + (--number));
}
}

//增操作
class NumberInfoAdd implements Runnable
{
private String name;
private NumberInfo nInfo;

public NumberInfoAdd(String name, NumberInfo nInfo)
{
 this.name = name;
 this.nInfo = nInfo;
}

public void run()
{
 add();
}

public void add()
{
synchronized (nInfo)
 {
  System.out.print(name + "--");
  nInfo.add();
 }
}
}

//减操作
class NumberInfoMinus implements Runnable
{
private String name;
private NumberInfo nInfo;

public NumberInfoMinus(String name, NumberInfo nInfo)
{
 this.name = name;
 this.nInfo = nInfo;
}

public void run()
{
 minus();
}

public void minus()
{
synchronized (nInfo)
 {
  System.out.print(name + "--");
  nInfo.minus();
 }
}
}


方法2:
public class MultiThreadShareData4
{
int j = 10;
public static void main(String[] args)
{
 MultiThreadShareData4 m = new MultiThreadShareData4();
 for (int i = 0; i < 2; i++)
 {
  new Thread(m.new NumberInfoAdd()).start();
  new Thread(m.new NumberInfoMinus()).start();
 }
}

public synchronized void add()
{
 System.out.println("
增加后数值:" + (++j));
}

public synchronized void minus()
{
 System.out.println("
減少后数值:" + (--j));
}

//
class NumberInfoAdd implements Runnable
{
 public void run()
 {
  add();
 }
}

//
class NumberInfoMinus implements Runnable
{
 public void run()
 {
  minus();
 }
}
}

执行结果可能是:

增线程--数值:11
增线程--数值:12
减线程--数值:11
减线程--数值:10

执行结果也可能是:
增线程--数值:11
减线程--数值:10
减线程--数值:9
增线程--数值:10

其实线程执行相同代码也可以按照这些方法来做,看一个方法1:

public class MultiThreadShareData2
{
public static void main(String[] args)
{
 TicketInfo tInfo = new TicketInfo(20);
 new Thread(new SaleTickets2("
线程1", tInfo)).start();
 new Thread(new SaleTickets2("线程2", tInfo)).start();
}
}

class TicketInfo
{
private int allTicketCount;

public TicketInfo(int allTicketCount)
{
 this.allTicketCount = allTicketCount;
}

public int getAllTicketCount()
{
 return allTicketCount;
}

public void setAllTicketCount(int allTicketCount)
{
 this.allTicketCount = allTicketCount;
}

public void sale()
{
 System.out.println("
剩余:" + allTicketCount--);
}
}

class SaleTickets2 implements Runnable
{
private String name;
private TicketInfo tInfo;

public SaleTickets2(String name, TicketInfo tInfo)
{
 this.name = name;
 this.tInfo = tInfo;
}

public void run()
{
 while (tInfo.getAllTicketCount() > 0)
 {
  sale();
 }
}

public void sale()
{
 synchronized (tInfo)
 {
  System.out.print(name + "--");
  tInfo.sale();
 }
}
}

部分代码参考张孝祥老师线程视频源码。