一、每个线程做执行的代码相同
若每个线程执行的代码相同,共享数据就比较方便。可以使用同一个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 synchronizedvoid 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();
}
}
}
其实线程执行相同代码也可以按照这些方法来做,看一个方法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();
}
}
}
部分代码参考张孝祥老师线程视频源码。