線程間共享數據
一、每個線程執行的代碼相同
若每個線程執行的代碼相同,共享數據就比較方便。可以使用同一個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();
}
}
}
部分代碼參考張孝祥老師線程視頻源碼。
最後更新:2017-04-03 12:55:00