线程间共享数据

简介:

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

若每个线程执行的代码相同,共享数据就比较方便。可以使用同一个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();
  }
 }
}

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

 

目录
相关文章
|
存储 Java Unix
什么是线程?为什么需要线程?和进程的区别?
什么是线程?为什么需要线程?和进程的区别?
1743 0
|
安全 程序员 编译器
线程互斥、同步(一)
线程互斥、同步
87 1
|
安全 数据安全/隐私保护
线程互斥、同步(二)
线程互斥、同步
65 1
【并发技术08】多个线程间共享数据
【并发技术08】多个线程间共享数据
|
安全 数据库
【并发技术06】线程范围内共享数据
【并发技术06】线程范围内共享数据
|
存储 Java 数据库连接
【并发技术07】使用ThreadLocal在线程范围内共享数据
【并发技术07】使用ThreadLocal在线程范围内共享数据
|
存储 Linux 调度
Linux多线程:线程概念、线程间的独有与共享、多线程VS多进程,线程控制:线程创建、线程终止、线程等待、线程分离
Linux多线程:线程概念、线程间的独有与共享、多线程VS多进程,线程控制:线程创建、线程终止、线程等待、线程分离
234 0
|
Java
正确使用锁保护共享数据,协调异步线程(上)
正确使用锁保护共享数据,协调异步线程
144 0
|
安全 Java 程序员
正确使用锁保护共享数据,协调异步线程(下)
正确使用锁保护共享数据,协调异步线程
326 0
多线程的关键是,不同线程对象要独立
多线程的关键是,不同线程对象要独立
116 0

相关实验场景

更多