线程间共享数据

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

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

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

 

时间: 2024-08-31 19:33:32

线程间共享数据的相关文章

线程间共享数据无需竞争

原文 地址  作者  Trisha   译者:李同杰 LMAX Disruptor 是一个开源的并发框架,并获得2011 Duke's程序框架创新奖.本文将用图表的方式为大家介绍Disruptor是什么,用来做什么,以及简单介绍背后的实现原理. Disruptor是什么? Disruptor 是线程内通信框架,用于线程里共享数据.LMAX 创建Disruptor作为可靠消息架构的一部分并将它设计成一种在不同组件中共享数据非常快的方法. 基于Mechanical Sympathy(对于计算机底层硬

共享内存-android系统进程间共享数据的同步问题

问题描述 android系统进程间共享数据的同步问题 想在android系统层写两个可执行程序(main_a,main_b),使用ndk-build编译. main_a 用来录音,main_b通过进程件套通信方式从main_a中把录音数据接收过来保存成文件.对于android来说,能想到的进程间通信方式是mmap,(匿名管道不行:命名管道有长度限制:匿名共享内存貌似得不到相同的文件句柄,而且内部也是使用mmap实现的).现在能用mmap共享数据,但是两个进程之间读写数据无法做同步.(据我了解li

C++进程间共享数据实例_C 语言

本文实例讲述了C++进程间共享数据的实现方法,分享给大家供大家参考.具体实现方法如下: 复制代码 代码如下: int main(int argc, char *argv[])  {      //RecursiveDelete("C:\\20_128\\");      //SelfRun("runModel");      //进程间内存共享      LPCTSTR lpName= "hello";      LPCTSTR lpConten

详解Laravel视图间共享数据与视图Composer_php实例

1.在视图间共享数据 除了在单个视图中传递指定数据之外,有时候需要在所有视图中传入同一数据,即我们需要在不同视图中共享数据.要实现这一目的,需要使用视图工厂的share方法. 全局帮助函数view和response类似,如果传入参数,则返回Illuminate\View\View实例,不传入参数则返回Illuminate\View\Factory实例.所以我们可以通过在服务提供者的boot方法中使用如下方式实现视图间共享数据: <?php namespace App\Providers; use

Python multiprocessing.Manager介绍和实例(进程间共享数据)_python

Python中进程间共享数据,处理基本的queue,pipe和value+array外,还提供了更高层次的封装.使用multiprocessing.Manager可以简单地使用这些高级接口. Manager()返回的manager对象控制了一个server进程,此进程包含的python对象可以被其他的进程通过proxies来访问.从而达到多进程间数据通信且安全. Manager支持的类型有list,dict,Namespace,Lock,RLock,Semaphore,BoundedSemaph

详解Laravel视图间共享数据与视图Composer

1.在视图间共享数据 除了在单个视图中传递指定数据之外,有时候需要在所有视图中传入同一数据,即我们需要在不同视图中共享数据.要实现这一目的,需要使用视图工厂的share方法. 全局帮助函数view和response类似,如果传入参数,则返回Illuminate\View\View实例,不传入参数则返回Illuminate\View\Factory实例.所以我们可以通过在服务提供者的boot方法中使用如下方式实现视图间共享数据: <?php namespace App\Providers; use

Android实现不同apk间共享数据的方法(2种方法)

本文实例讲述了Android实现不同apk间共享数据的方法.分享给大家供大家参考,具体如下: Android给每个APK进程分配一个单独的用户空间,其manifest中的userid就是对应一个Linux用户(Android 系统是基于Linux)的. 所以不同APK(用户)间互相访问数据默认是禁止的. 但是它也提供了2种APK间共享数据的形式: 1. Share Preference. / Content Provider APK可以指定接口和数据给任何其他APK读取. 需要自己实现接口和Sh

完整的网站间共享数据的WebService(Love.NET原创)

web|数据|原创 我记得好象有一个网友问过关于怎样在几个站点间共享数据库资源我在两台电脑上试验成功了我的代码是这样的提供大家参考在站点a的数据库服务器的数据库中有一个数据表NoteBoard包含字段ID(编号),Title(标题),NoterName(留言人名字),NoteTime(留言时间)怎样可以让站点b获得这个数据表的记录呢.在a定义访问a站数据库的webservice文件MyViewDBService.asmx<%@WebService Language="C#" Cl

Android多线程研究(5)线程之间共享数据

一.如果是每个线程都执行相同的代码,则可以使用同一个Runnable来实现共享 public class MultiThreadShareData { public static void main(String[] args) { new Thread(new ShareData()).start(); new Thread(new ShareData()).start(); } static class ShareData implements Runnable{ private int j