Java基础知识强化102:线程间共享数据
一、每个线程执行的代码相同:
若每个线程执行的代码相同,共享数据就比较方便。可以使用同一个Runnable对象,这个Runnable对象中就有那个共享数据。
public class MultiThreadShareData
{
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了。
二、每个线程执行的代码不相同:
方法:将需要共享的数据封装成一个对象,将该对象传给执行不同代码的Runnable对象。
方法:将这些执行不同代码的Runnable对象作为内部类。
看例子:有4个线程,其中有2个线程对每次对j +1,有2个线程对每次对j -1。加减操作无顺序。
(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)方法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基础知识强化102:线程间共享数据的更多相关文章
- Java并发基础09. 多个线程间共享数据问题
先看一个多线程间共享数据的问题: 设计四个线程,其中两个线程每次对data增加1,另外两个线程每次对data减少1. 从问题来看,很明显涉及到了线程间通数据的共享,四个线程共享一个 data,共同操作 ...
- Java基础知识强化之集合框架笔记76:ConcurrentHashMap之 ConcurrentHashMap简介
1. ConcurrentHashMap简介: ConcurrentHashMap是一个线程安全的Hash Table,它的主要功能是提供了一组和Hashtable功能相同但是线程安全的方法.Conc ...
- 详解 Qt 线程间共享数据(用信号槽方式)
使用共享内存.即使用一个两个线程都能够共享的变量(如全局变量),这样两个线程都能够访问和修改该变量,从而达到共享数据的目的. Qt 线程间共享数据是本文介绍的内容,多的不说,先来啃内容.Qt线程间共享 ...
- Disruptor 线程间共享数据无需竞争
队列的作用是缓冲 缓冲到 队列的空间里.. 线程间共享数据无需竞争 原文 地址 作者 Trisha 译者:李同杰 LMAX Disruptor 是一个开源的并发框架,并获得2011 Duke’ ...
- 详解 Qt 线程间共享数据(使用signal/slot传递数据,线程间传递信号会立刻返回,但也可通过connect改变)
使用共享内存.即使用一个两个线程都能够共享的变量(如全局变量),这样两个线程都能够访问和修改该变量,从而达到共享数据的目的. Qt 线程间共享数据是本文介绍的内容,多的不说,先来啃内容.Qt线程间共享 ...
- Qt学习:线程间共享数据(使用信号槽传递数据,必须提前使用qRegisterMetaType来注册参数的类型)
Qt线程间共享数据主要有两种方式: 使用共享内存.即使用一个两个线程都能够共享的变量(如全局变量),这样两个线程都能够访问和修改该变量,从而达到共享数据的目的: 使用singal/slot机制,把数据 ...
- Java基础知识强化100:JVM 内存模型
一. JVM内存模型总体架构图: 方法区和堆由所有线程共享,其他区域都是线程私有的 二. JVM内存模型的结构分析: 1. 类装载器(classLoader) 类装载器,它是在java虚拟机中用途是 ...
- JAVA 并发编程-多个线程之间共享数据
原文地址:http://blog.csdn.net/hejingyuan6/article/details/47053409# 多线程共享数据的方式: 1,如果每个线程执行的代码相同,可以使用同一个R ...
- JAVA 并发编程-多个线程之间共享数据(六)
多线程共享数据的方式: 1.假设每一个线程运行的代码同样.能够使用同一个Runnable对象,这个Runnable对象中有那个共享数据,比如,卖票系统就能够这么做. 2,假设每一个线程运行的代码不同. ...
随机推荐
- PHP命名规范【转】
[转]谭博的个人网站 [类] 1.类名与类文件名采用驼峰式且首字母大写 2.类私有属性和私有方法名称以下划线开头 3.方法名使用驼峰式 [变量] 变量名使用小写字母加下划线 [函数] 函数名使用小 ...
- 关于登录的会话控制, 终极解决方案 - chunyu
登录是用cookie还是session实现,一直有争议,普遍认为session更安全,可是有些功能,用cookie最方便也最高效,比如“记住我一周”. cookie还是session,我的答案是两 ...
- 开元硬件平台 Arduino
开放源代码的电路图设计,程序开发接口免费下载,也可依个人需求自己修改. Arduino不仅仅是全球最流行的开源硬件,也是一个优秀的硬件开发平台,更是硬件开发的趋势.Arduino简单的开发方式使得开发 ...
- dedecms
http://www.duodede.com/free/ [free templte] http://www.xiuzhanwang.net/d
- 转】Apache解决高并发和高可用
原博主于: http://www.ha97.com/5803.html 感谢! 服务器集群 Apache 和 nginx(web服务器) 1. 多台集群机器联合处理一个任务. 2. 一台机器处 ...
- 通过源码学Java基础:InputStream、OutputStream、FileInputStream和FileOutputStream
1. InputStream 1.1 说明 InputStream是一个抽象类,具体来讲: This abstract class is the superclass of all classes r ...
- linux信号量超过系统限制
部署一台新服务器,信号量报错,观察也没有key冲突,错误分析及解决如下: 创建一个不存在的信号量集返回参数错误的报错,因为信号量集的信号量数量超过了系统限制. 系统默认 /home/poc#ipcs ...
- BaiduMap开发,获取公交站点信息。
可能有些人会出现无法导入overlayutil的错误,这是因为BaiduMap里面的包把这部分删除掉了,并且官方没有给出说明,这个地方以前也是让我折腾了很久. 不知道现在有没有说明这个问题,如果需要这 ...
- [刷题codeforces]651B/651A
651B Beautiful Paintings 651A Joysticks 点击可查看原题 651B是一个排序题,只不过多了一步去重然后记录个数.每次筛一层,直到全为0.从这个题里学到一个正确姿势 ...
- Nginx学习之十一-Nginx启动框架处理流程
Nginx启动过程流程图 下面首先给出Nginx启动过程的流程图: ngx_cycle_t结构体 Nginx的启动初始化在src/core/nginx.c的main函数中完成,当然main函数是整个N ...