您的位置:首页 > 其它

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

2012-09-04 17:53 911 查看
一.
这里跟大家分享一下售票系统,这里是一个抢票系统,讨论一下线程同步的作用(关键字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 DeadLock
implements 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 MyLock
ml1 =
new MyLock();

static MyLock
ml2 =
new MyLock();

}

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

Thread-1这是else语句的ml2

可见死锁现象已浮出水面,这里的两个线程都只运行了一步,下一步则被互相牵制,即互斥锁。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐