java多线程信息共享
上篇文章知识介绍了多线程的创建和启动问题,各个子线程和子线程或者说子线程和main线程没有信息的交流,这篇文章主要探讨线程之间信息共享以及交换问题。这篇文章主要以一个卖票例子来展开。
继承Thread重写run方法进行实现
初始代码:
public class Tickect1 {
public static void main(String[] args) {
//创建四个线程进行测试
new Thread3().start();
new Thread3().start();
new Thread3().start();
new Thread3().start();
}
}
class Thread3 extends Thread{
private static int tickets = 100;//总票数
@Override
public void run() {
while(true){
if(tickets<=0){
break;
}else{
System.out.println(Thread.currentThread().getName()+" "+tickets);
tickets--;
}
}
}
}
错误答案:卖了103张票

分析原因:1.类似于i++的操作不是原子操作


四个进程有四个工作缓存,每次都是修改工作缓存的数据,而且四个工作缓存之间的数据无法共享,倒置在缓存1中已经tickets-1,但是缓存2中tickets又无法获取1中缓存的数据所以票会增大,所以出现103
2.关键步骤缺少加锁操作(获取票数和对票数-1的操作同时执行会出现问题)


改进的代码:这个代码有bug,测试答案还是103
public class Tickect1 {
public static void main(String[] args) {
//创建四个线程进行测试
new Thread3().start();
new Thread3().start();
new Thread3().start();
new Thread3().start();
}
}
class Thread3 extends Thread{
private static volatile int tickets = 100;//总票数
@Override
public void run() {
while(true){
sale();
if(tickets<=0) break;
}
}
public synchronized void sale(){//对数据修改进行加锁(同一时刻只能一个线程执行)
if(tickets>0){
System.out.println(Thread.currentThread().getName()+" "+tickets);
tickets--;
}
}
}
实现Runnable的run方法进行实现
public class Ticket2 {
public static void main(String[] args) {
Thread4 t = new Thread4();
new Thread(t).start();
new Thread(t).start();
new Thread(t).start();
new Thread(t).start();
}
}
class Thread4 implements Runnable{
private volatile int tickets=100;//volatile起到通知各个线程缓存区的数据是否修改,如果修改就刷新缓冲区数据(变量副本的解决方法)
String str = new String("");//对这个对象加锁
@Override
public void run() {
while (true){
//sale();方式1
synchronized (str){//代码快加锁(方式2)
if(tickets>0){
System.out.println(Thread.currentThread().getName()+" "+tickets);
tickets--;
}
}
if(tickets<=0) break;
}
}
public synchronized void sale(){//synchronized对数据修改进行加锁(同一时刻只能一个线程执行)
if(tickets>0){//必须在这里判断,if放在外面会出现错误
System.out.println(Thread.currentThread().getName()+" "+tickets);
tickets--;
}
}
}

volatile关键字测试
public class ThreadDemo2
{
public static void main(String args[]) throws Exception
{
TestThread2 t = new TestThread2();
t.start();
Thread.sleep(2000);
t.flag = false;
System.out.println("main thread is exiting");
}
}
class TestThread2 extends Thread
{
//boolean flag = true; //子线程不会停止
volatile boolean flag = true; //用volatile修饰的变量可以及时在各线程里面通知
public void run()
{
int i=0;
while(flag)
{
i++;
}
System.out.println("test thread3 is exiting");
}
}
java多线程信息共享的更多相关文章
- JAVA多线程之间共享数据BlockingQueue介绍
在JAVA的Concurrent包中,BlockingQueue很好的解决了多线程中,如何高效安全“传输”数据的问题.通过这些高效并且线程安全的队列类,为我们快速搭建高质量的多线程程序带来极大的便利. ...
- java——多线程——内部类共享同一个外部类对象的成员变量
public class Shop { public static void main(String[] args) { Outer o=new Outer(); Thread t1=o.getSal ...
- 循序渐进Java Socket网络编程(多客户端、信息共享、文件传输)
目录[-] 一.TCP/IP协议 二.TCP与UDP 三.Socket是什么 四.Java中的Socket 五.基本的Client/Server程序 六.多客户端连接服务器 七.信息共享 八.文件传输 ...
- JAVA Socket(多个客户同时连接,信息共享) client (java/ruby)
第一步 充分理解Socket 1.什么是socket 所谓socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄.应用程序通常通过"套接字" ...
- Java多线程调试如何完成信息输出处理
转载自:http://developer.51cto.com/art/201003/189078.htm Java多线程调试是很繁琐的,但是还是需要我们不断进行相关的学习.下面我们就来看看在Java多 ...
- Java多线程——查看线程堆栈信息
Java多线程——查看线程堆栈信息 摘要:本文主要介绍了查看线程堆栈信息的方法. 使用Thread类的getAllStackTraces()方法 方法定义 可以看到getAllStackTraces( ...
- 40个Java多线程问题总结
前言 Java多线程分类中写了21篇多线程的文章,21篇文章的内容很多,个人认为,学习,内容越多.越杂的知识,越需要进行深刻的总结,这样才能记忆深刻,将知识变成自己的.这篇文章主要是对多线程的问题进行 ...
- Java多线程干货系列—(一)Java多线程基础
前言 多线程并发编程是Java编程中重要的一块内容,也是面试重点覆盖区域,所以学好多线程并发编程对我们来说极其重要,下面跟我一起开启本次的学习之旅吧. 正文 线程与进程 1 线程:进程中负责程序执行的 ...
- Java多线程系列--“JUC锁”08之 共享锁和ReentrantReadWriteLock
概要 Java的JUC(java.util.concurrent)包中的锁包括"独占锁"和"共享锁".在“Java多线程系列--“JUC锁”02之 互斥锁Ree ...
随机推荐
- JS全选按钮练习
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/ ...
- 利用Marshal来管理非托管资源
void MarshalChartDemo() { string name = "xuwei"; IntPtr pName = Marshal.AllocHGlobal(name. ...
- Your wechat account may be LIMITED to log in WEB wechat, error info: <error><ret>1203</ret><message>为了你的帐号安全,此微信号不能登录网页微信。你可以使用Windows微信或Mac微信在电脑端登录。Windows微信下载地址:WeChat for PC
转载:https://zhuanlan.zhihu.com/p/76180564 微信网页版限制登录或禁止登录将影响一大批使用itchat等Web Api方案的微信机器人 网页版微信 API 被封了, ...
- fnt文字
//fileName是fnt文件的path.在fnt文件的相同目录下有同名png文件.使用ShoeBox.exe生成fnt文件.在fnt文件中修改路径为类似number 及 number.png的格式 ...
- x = cos x 的解析形式
x = cos x 的解析形式 玩计算器的发现 大家都玩过计算器吧, 不知注意到没有. 输入任意数, 然后不断按最后总会输出. 什么, 你说明明记得是:? 哦, 因为你用了角度制. 这一系列操作等价于 ...
- 题解【AcWing274】移动服务
题面 非常好的优化 \(\text{DP}\) 状态表示的题目. 首先可以设 \(dp_{i,x,y,z}\) 表示已经做完了前 \(i\) 个请求,现在的 \(3\) 名服务员分别在 \(x\) . ...
- jvm 结构分析
jvm区域总体分两类,heap区和非heap区.heap区又分: Eden Space(伊甸园).Survivor Space(幸存者区).Tenured Gen(老年代-养老区). 非heap区又分 ...
- 变色html css js
<!DOCTYPE html><html> <head> <meta charset="utf-8" /> <title> ...
- vuecli+axios的post请求传递参数异常
大多数的web服务器只能识别form的post的请求,即请求头Content-Type为’application/x-www-form-urlencoded‘ axios.defaults.heade ...
- FP side-effects
https://medium.com/javascript-scene/master-the-javascript-interview-what-is-a-pure-function-d1c076be ...