修改练习1卖票例子,先让它网络延迟,出现问题,再解决问题。
1)同步代码块
class Ticket implements Runnable {
private Integer num = 50;
@Override
public void run() {
for (int i = 0; i < 200; i++) {
sale();
}
}
private Object o = new Object();// 作为监听对象
/**
* 卖票
*/
public void sale() {
synchronized (o) {
if (num > 0) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "卖出了第"
+ num-- + "张票");
}
}
}
}
public class TicketDemo {
public static void main(String[] args) {
Runnable target = new Ticket();
new Thread(target, "A").start();
new Thread(target, "B").start();
new Thread(target, "C").start();
}
}
2)方法2:同步方法
class Ticket implements Runnable {
private Integer num = 50;
@Override
public void run() {
for (int i = 0; i < 200; i++) {
sale();
}
}
/**
* 卖票
*/
public synchronized void sale() {
if (num > 0) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "卖出了第"
+ num-- + "张票");
}
}
}
public class TicketDemo {
public static void main(String[] args) {
Runnable target = new Ticket();
new Thread(target, "A").start();
new Thread(target, "B").start();
new Thread(target, "C").start();
}
}
3)可重入锁
import java.util.concurrent.locks.ReentrantLock;
class Ticket implements Runnable {
private Integer num = 50;
private ReentrantLock lock = new ReentrantLock();
@Override
public void run() {
for (int i = 0; i < 200; i++) {
sale();
}
}
/**
* 卖票
*/
public void sale() {
lock.lock();
if (num > 0) {
try {
Thread.sleep(1);
System.out.println(Thread.currentThread().getName()
+ "卖出了第" + num-- + "张票");
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
}
public class TicketDemo {
public static void main(String[] args) {
Runnable target = new Ticket();
new Thread(target, "A").start();
new Thread(target, "B").start();
new Thread(target, "C").start();
}
}