读书人

经验3-由售票系统中的抢票机制解说同步

发布时间: 2012-09-09 09:27:54 作者: rapoo

心得3--由售票系统中的抢票机制解说同步线程及死锁案例分析

一. 这里跟大家分享一下售票系统,这里是一个抢票系统,讨论一下线程同步的作用(关键字synchronized),第一种是正确的程序,下面两种分别是两种不同的错误。

1.运用synchronized同步做的售票程序

packagecom.javaEE.code.synchronizedDemo;

classSellTicket{
public static int tickets = 10;
public synchronized void action(String name){
System.out.println(name+"抢到了"+tickets+"号票");
tickets--;
try {
Thread.sleep(20);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class TicketThread extends Thread{
String name;
SellTicket t;
public TicketThread(SellTicket t, String name) {
this.t = t;
this.name = name;
start();
}
public void run() {
for(int i=0;i<5;i++){
t.action(name);
}
}
}
public class TestTicket{
public static void main(String[] args) {
SellTicket t = new SellTicket();
TicketThread t1 = new TicketThread(t,"小刚");
TicketThread t2 = new TicketThread(t,"洋洋");
}
}
2.sychronized的特殊情况(错误1)

packagecom.javaEE.code.synchronizedDemo;
/**
* 这种情况就是synchronized的特殊情况,同一个类的不同对象不能用这种方法上锁。
* */
public class Ticket extends Thread {
String name;
public static int tickets = 10;
public Ticket(String name, int tickets) {
super();
this.name = name;
Ticket.tickets = tickets;
}
//这里的锁方法是不管用的。
public synchronized void action(String name){
System.out.println(name+"抢到了"+tickets+"号票");
tickets--;
try {
Thread.sleep(20);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
Ticket t1 = new Ticket("小刚",tickets);
Ticket t2 = new Ticket("洋洋",tickets);
t1.start();
t2.start();
}
public void run() {
for(int i=0;i<5;i++){
action(name);
}
}
}
3.不用同步做的存在安全隐患的售票系统(错误2)

packagecom.javaEE.code.synchronizedDemo;
/**
* 这种情况是一种错误的情况,两人同时抢票,可能第一个人强的票刚售出去(输出),总票数还没减去这张票,第二个人又来买票,这时就有可能买的是同一张票了。
* */
public class TicketError extends Thread {
String name;
public static int tickets = 10;
public TicketError(String name, int tickets) {
super();
this.name = name;
TicketError.tickets = tickets;
}
public static void main(String[] args) {
TicketError t1 = new TicketError("小刚",tickets);
TicketError t2 = new TicketError("洋洋",tickets);
t1.start();
t2.start();
}
public void run() {
for(int i=0;i<5;i++){
System.out.println(name+"抢到了"+tickets+"号票");
tickets--; //这里未减一第二个人就来抢票了
try {
Thread.sleep(20);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}

二. 死锁案例及分析

packagecom.javaEE.code.deadLock;

publicclass DeadLockimplements Runnable{

privatebooleanflag;

public DeadLock(boolean flag) {

this.flag = flag;

}

publicstaticvoid main(String[]args) {

DeadLock dl1 = new DeadLock(true);

DeadLock dl2 = new DeadLock(false);

Thread t1 = new Thread(dl1);

Thread t2 = new Thread(dl2);

t1.start();

t2.start();

}

@Override

publicvoid run() {

//if(){}else{}嵌套,模拟死锁

if(flag){

synchronized(MyLock.ml1){

System.out.println(Thread.currentThread().getName()+"这是if语句的ml1");

synchronized(MyLock.ml2){

System.out.println(Thread.currentThread().getName()+"这是if语句的ml2");

}

}

}else{

synchronized(MyLock.ml2){

System.out.println(Thread.currentThread().getName()+"这是else语句的ml2");

synchronized(MyLock.ml1){

System.out.println(Thread.currentThread().getName()+"这是else语句的ml1");

}

}

}

}

}

/**

*自定义锁,被同步代码块synchronized所调用

* */

class MyLock{

static MyLockml1 = new MyLock();

static MyLockml2 = new MyLock();

}

输出结果为:Thread-0这是if语句的ml1

Thread-1这是else语句的ml2

可见死锁现象已浮出水面,这里的两个线程都只运行了一步,下一步则被互相牵制,即互斥锁。

读书人网 >编程

热点推荐