java多线程共享_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张票

1139c5e79cc4938c460ce0354f67a211.png

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

d4971a4ba48965ddb8bf52fe44a876b7.png

9ca791b31b1e2b24027c87f148559c0c.png

四个进程有四个工作缓存,每次都是修改工作缓存的数据,而且四个工作缓存之间的数据无法共享,倒置在缓存1中已经tickets-1,但是缓存2中tickets又无法获取1中缓存的数据所以票会增大,所以出现103

2.关键步骤缺少加锁操作(获取票数和对票数-1的操作同时执行会出现问题)

019780eb1af480dfdcb55aa211132428.png

41a5d400bf343dd3c3f6af4104a95925.png

改进的代码:这个代码有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--;

}

}

}

b197e846d528b205ee50b5fe87953ca3.png

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");

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值