在java中当开启多个线程的时候,因为操作的同一内存容易造成数量上的错误
public class Ticket {
int num;
public Ticket(int num) {
this.num = num;
}
public Ticket() {
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public void sell() {
while (num > 0) {
System.out.println(Thread.currentThread().getName() + "卖出第" + num + "张票");
num--;
}
}
}
public class Main {
public static void main(String[] args) {
Ticket ticket = new Ticket(20);
new Thread( () -> {
ticket.sell();
},"窗口1").start();
ticket.sell();
}
}
这个时候运行结果
main卖出第20张票
窗口1卖出第20张票
窗口1卖出第18张票
窗口1卖出第17张票
窗口1卖出第16张票
窗口1卖出第15张票
窗口1卖出第14张票
main卖出第19张票
窗口1卖出第13张票
窗口1卖出第11张票
main卖出第12张票
窗口1卖出第10张票
窗口1卖出第8张票
窗口1卖出第7张票
窗口1卖出第6张票
窗口1卖出第5张票
窗口1卖出第4张票
窗口1卖出第3张票
窗口1卖出第2张票
窗口1卖出第1张票
main卖出第9张票
Process finished with exit code 0
在买票过程中 两次卖出同一张票,这是因为当窗口一拿出数据还没有返回的时候,main就拿走了老数据,所以要加一把锁,使得窗口1还没有返回数据的时候,main不可以拿走数据。
public class Ticket {
int num;
public Ticket(int num) {
this.num = num;
}
public Ticket() {
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public void sell() {
while (num > 0) {
synchronized (this) {
System.out.println(Thread.currentThread().getName() + "卖出第" + num + "张票");
num--;
}
}
}
}
再一次运行,查看结果
main卖出第20张票
窗口1卖出第19张票
窗口1卖出第18张票
窗口1卖出第17张票
窗口1卖出第16张票
窗口1卖出第15张票
窗口1卖出第14张票
窗口1卖出第13张票
窗口1卖出第12张票
main卖出第11张票
main卖出第10张票
main卖出第9张票
main卖出第8张票
main卖出第7张票
main卖出第6张票
窗口1卖出第5张票
窗口1卖出第4张票
窗口1卖出第3张票
窗口1卖出第2张票
窗口1卖出第1张票
main卖出第0张票
Process finished with exit code 0
这次就没有出错了。synchronized (this)其中的this指的是调用这个的对象,比如main方法中的ticket。