public class Ticket implements Runnable{
private int num = 50;
@Override
public void run() {
while(true){
if(num > 0){
System.out.println(Thread.currentThread().getName() + "卖出第" + (51-num) + "张票");
num--;
}else{
break;
}
}
}
public static void main(String[] args) {
//两线程要共享同个对象
Ticket t = new Ticket();
new Thread(t).start();
new Thread(t).start();
}
}
以上数据混乱,数据不正确
public class Ticket2 implements Runnable{
private static int num = 50;
@Override
public void run() {
while(true){
if(num > 0){
System.out.println(Thread.currentThread().getName() + "卖出第" + (51-num) + "张票");
num--;
}else{
break;
}
}
}
public static void main(String[] args) {
//两线程要共享同个对象
Ticket2 t = new Ticket2();
new Thread(t).start();
new Thread(t).start();
}
}
以上数据混乱,数据不正确
public class Ticket3 implements Runnable{
private static int num = 50;
@Override
public void run() {
while(true){
//这个是对象锁,要么全部执行,要么全部不执行,类似于事务
//synchronized修饰非静态成员方法默认为this锁
synchronized(this){
if(num > 0){
//有两处代码以上会产生并发操作,会导致数据混乱,必须加锁
System.out.println(Thread.currentThread().getName() + "卖出第" + (51-num) + "张票");
num--;
}else{
break;
}
}
}
}
public static void main(String[] args) {
//两线程要共享同个对象,执行的是同一个run方法
Ticket3 t = new Ticket3();
new Thread(t).start();
new Thread(t).start();
}
}
以上正确了,也可改用继承线程的方式实现,代码如下:
public class Ticket3 extends Thread{
private static int num = 50;
@Override
public void run() {
while(true){
//此时不能用对象锁了,两线程执行各自的run方法,如果是对象锁,
//则各自用自己的,即独享,所以要用静态锁,共享才可以
//synchronized(this){
synchronized(Ticket3.class){
if(num > 0){
//有两处代码以上会产生并发操作,会导致数据混乱,必须加锁
System.out.println(Thread.currentThread().getName() + "卖出第" + (51-num) + "张票");
num--;
}else{
break;
}
}
}
}
public static void main(String[] args) {
//两线程执行各自的run方法,如果是对象锁,
//则各自用自己的,所以要用静态锁,共享才可以
new Ticket3().start();
new Ticket3().start();
}
}