在能同步的地方都已经同步了,为什么还是发生线程污染?
问题
这是一段Java学习中的例程,四个车站分别抢票。但是无法实现线程安全。
需求
实现线程安全
注释
saleT代表车站的类
静态类balance代表剩余的票数
s1-s4分别代表四个车站
我在能用sync修饰的地方都打上了sync,为什么还是无法实现线程安全?
↓下面是代码内容
package com.hssgweb.多线程;
//import java.util.concurrent.locks.ReentrantLock;
class balance{
static double b = 1000;
public static double getB() {
return b;
}
public static void setB(double b) {
balance.b = b;
}
}
public class 铁路12306 {
public static void main(String[] args) { //主方法
SaleT s1 = new SaleT("1号");
SaleT s2 = new SaleT("2号");
SaleT s3 = new SaleT("3号");
SaleT s4 = new SaleT("4号");
Thread th1 = new Thread(s1);
Thread th2 = new Thread(s2);
Thread th3 = new Thread(s3);
Thread th4 = new Thread(s4);
th1.start();
th2.start();
th3.start();
th4.start();
}
}
class SaleT implements Runnable {
// Lock lock = new ReentrantLock();
String saleId;
double balan;
public SaleT(String saleId ) {
super();
this.saleId = saleId;
}
synchronized void pay(){ //pay方法
balan = balance.getB()-1; //剩余票数等于原来的票数减1
balance.setB(balan);
/*System.out.println(balan);
balan = ti.b.getB();*/
}
int i = 0; //记录一下这玩意儿总共抢了多少张票
public synchronized void run() {
while(balance.getB() > 0) {
pay();
System.out.println("我是" + saleId + "我为自己代言" + "---还剩下" + balance.getB());
i++;
}
System.out.println("我是" + saleId + "我抢了" + i);
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
你同步啥了...synchronized方法锁的是实例对象 你4个对象 每个对象一把锁 自己和自己抢锁 谁都能进去 哪里同步了
synchronized
关键字的底层实现是对象锁,它是作用于某一个对象上的。对于一个以synchronized修饰的方法来说,如果它不是静态方法,那么加锁的对象就是本对象即this;如果它是静态方法,那么加锁的对象是这个类的Class对象(可以用getClass()获得)。在你的代码中,s1、s2、s3和s4是四个不同的对象,因此有四把不同的锁分别控制这四个对象的
run()
方法,这四个线程同时操作同一个静态变量balance.b
,四把锁之间是互不影响的,因此这个代码根本就没有体现任何的线程安全。你应该使用同一把锁控制这四个线程对b的读写过程,或者将b修改为原子类型。