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,假设每一个线程运行的代码不同. ...
随机推荐
- css水平居中和垂直居中
水平居中:内联元素:text-align:center;相对于父级居中显示块级元素:margin:0 auto;但是需要同时width,否则无法看到效果多个块级元素居中:在此想要探讨一下display ...
- EasyMock(官方资料整理)
1.要求 EasyMock要求java1.5.0及以上版本. Objenesis (2.0+)必须在classpath中来执行class mocking. 2.使用Maven 在Maven中心库中可以 ...
- TJOI2013 DAY2
第一题:明显先处理出最终序列,然后用线段树求解.处理最终序列可以用二分加树状数组(时间复杂度log2n, 用平衡树也可以搞...). /* * Problem: TJOI2013-day2-Seque ...
- 递归函数recursion
1(调用自身)递归函数是‘自己调用自己‘的函数,不管这样的调用是直接的还是间接的. 2(递归出口)因为函数不可以一直调用自己,无法停止工作,所以递归函数一定具备结束条件. http://www.cnb ...
- codeforces 630H (组合数学)
H - Benches Time Limit:500MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Submit S ...
- FIREDAC连接SQLITE乱码的解决
在好多群里面都碰到问“FIREDAC连接SQLITE乱码的”的问题的同仁,遂将解决方法贴出来: 如上图所示设置 stringFormat为unicode即可
- VB.NET开发中遇到的一点小问题
在用vb.net开发的security support时,遇到一个问题,在trainingCourses.aspx页面上增加了一个HyperLink控件 <asp:HyperLink runat ...
- POJ 3041 Asteroids (二分图最小点覆盖)
题目链接:http://poj.org/problem?id=3041 在一个n*n的地图中,有m和障碍物,你每一次可以消除一行或者一列的障碍物,问你最少消除几次可以将障碍物全部清除. 用二分图将行( ...
- RSS阅读器(一)——dom4j读取xml(opml)文件
接触java不久,偶有收获,最近想做一个web版RSS阅读器来锻炼一下.手头有几个从不同版本的foxmail中导出的opml文件,大家应该都知道,opml文件就是xml格式的.那么就先从这里入手,练习 ...
- python 循环
200 ? "200px" : this.width)!important;} --> 介绍 python中有两种循环,分别是for...in循环.while循环:for.. ...