多线程学习二:售票案例
如果有多个线程在同时运行,而这些线程可能会同时运行这段代码。程序每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。
我们来模拟电影院的售票窗口,实现多个窗口同时卖 “功夫熊猫3”这场电影票(多个窗口一起卖这100张票);
同步代码块中的锁对象可以是任意的对象;但多个线程时,要使用同一个锁对象才能够保证线程安全。
package com.test;
public class ThreadDemo05 {
public static void main(String[] args) {
//创建票对象
Ticket ticket = new Ticket();
//创建3个窗口
Thread t1 = new Thread(ticket, "窗口1");
Thread t2 = new Thread(ticket, "窗口2");
Thread t3 = new Thread(ticket, "窗口3");
t1.start();
t2.start();
t3.start();
}
}
//模拟票
class Ticket implements Runnable {
//共100票
int ticket = 100;
//定义锁对象
Object lock = new Object();
@Override
public void run() {
//模拟卖票
while(true){ //无限循环,否则只会执行三次
//同步代码块
synchronized (lock){
if (ticket > 0) {
//模拟电影选坐的操作
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "正在卖票:" + ticket--);
}
}
}
}
}
同步方法中的锁对象是 this
使用同步方法,对电影院卖票案例中Ticket类进行如下代码修改:
package com.test;
public class ThreadDemo05 {
public static void main(String[] args) {
//创建票对象
Ticket ticket = new Ticket();
//创建3个窗口
Thread t1 = new Thread(ticket, "窗口1");
Thread t2 = new Thread(ticket, "窗口2");
Thread t3 = new Thread(ticket, "窗口3");
t1.start();
t2.start();
t3.start();
}
}
//模拟票
class Ticket implements Runnable {
//共100票
int ticket = 50;
boolean flag = true;
@Override
public void run() {
//模拟卖票
while(flag){
//同步方法
method();
}
}
//同步方法,锁对象this
public synchronized void method(){
if (ticket > 0) {
//模拟选坐的操作
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "正在卖票:" + ticket--);
}else {
flag = false;
}
}
}
学海无涯 代码作伴