我们通过多线程模拟售票窗口进行卖票。通过以上三种方式都可以解决同 步问题!
public class Test01 {
public static void main(String[] args) {
RunnableImpl r = new RunnableImpl();
new Thread(r,"窗口1").start();
new Thread(r,"窗口2").start();
}
}
实现类
public class RunnableImpl implements Runnable{
private int ticket = 100;
@Override
public void run(){
while (true){
if (ticket <= 0){
break;
}
try {
Thread.sleep(200);
String name = Thread.currentThread().getName();
System.out.println(name+"正在卖出第"+(100-ticket+1)+"张票,还剩余"+(--ticket)+"张");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
可以发现结果出现了剩余票数为负数-1; 多卖票,最后卖到101张了; 可能重复卖票,同一张票被卖了两次的情况
public class Test0 {
public static void main(String[] args) {
RunnableImpl1 r1 = new RunnableImpl1();
new Thread(r1,"①窗口1").start();
new Thread(r1,"①窗口2").start();
}
}
public class RunnableImpl1 implements Runnable{
private int ticket = 100;
@Override
public void run(){
while (true){
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (this){
if (ticket <= 0){
break;
}
String name = Thread.currentThread().getName();
System.out.println(name+"正在卖出第"+(100-ticket+1)+"张票,还剩余"+(--ticket)+"张");
}
}
}
}
public class Test02 {
public static void main(String[] args) {
RunnableImpl2 r2 = new RunnableImpl2();
new Thread(r2,"①窗口2").start();
new Thread(r2,"①窗口2").start();
}
}
public class RunnableImpl2 implements Runnable {
private static int ticket = 100;
@Override
public void run() {
//method();
staticmethod();
}
//静态方法,锁对象是当前本类的类.class字节码对象
private static synchronized void staticmethod() {
while (true){
if (ticket <= 0){
break;
}
try {
Thread.sleep(50);
String name = Thread.currentThread().getName();
System.out.println(name+"正在卖出第"+(100-ticket+1)+"张票,还剩余"+(--ticket)+"张");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
//非静态方法,锁对象是默认当前本类对象(this)
public synchronized void method(){
while (true){
if (ticket <= 0){
break;
}
try {
Thread.sleep(50);
String name = Thread.currentThread().getName();
System.out.println(name+"正在卖出第"+(100-ticket+1)+"张票,还剩余"+(--ticket)+"张");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Test03 {
public static void main(String[] args) {
RunnableImpl3 r3 = new RunnableImpl3();
new Thread(r3,"③窗口1").start();
new Thread(r3,"③窗口2").start();
}
}
public class RunnableImpl3 implements Runnable{
private int ticket = 100;
Lock l = new ReentrantLock();//更符合面向对象的思想
@Override
public void run(){
while (true){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
l.lock();
if (ticket <= 0){
l.unlock();
break;
}
try {
Thread.sleep(100);
String name = Thread.currentThread().getName();
System.out.println(name+"正在卖出第"+(100-ticket+1)+"张票,还剩余"+(--ticket)+"张");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
l.unlock();
}
}
}
}
本文由 Alicyu 创作,如果您觉得本文不错,请随意赞赏
采用 知识共享署名4.0 国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
原文链接:https://www.alicyu.com/archives/threads
最后更新:2019-10-18 14:30:13
Update your browser to view this website correctly. Update my browser now