您的位置:首页 > 编程语言 > Java开发

java 多线程详解二 买票示例

2016-08-30 21:53 531 查看
问题描述:写一个卖票程序,假设有10张票(实际可能有几百万张),有3个窗口同时售票,打印显示卖出的每张票。

(1)实现方式一(错误示例):

public class Ticket implements Runnable {
int num = 10;

@Override
public void run() {
while (num>0) {
num--;
System.out.println(Thread.currentThread().getName() + ":" + num);
}
}
}


public class TicketDemo {
public static void main(String[] args) {
Ticket ticket=new Ticket();
Thread thread1=new Thread(ticket);
Thread thread2=new Thread(ticket);
Thread thread3=new Thread(ticket);
thread1.start();
thread2.start();
thread3.start();
}
}


Thread-0:9
Thread-0:8
Thread-0:7
Thread-0:6
Thread-0:5
Thread-0:4
Thread-0:3
Thread-0:2
Thread-0:1
Thread-0:0

Process finished with exit code 0


发现结果符合题意,依次打印出车票。结果正确。下面我们修改程序,每卖出一张票休眠200毫秒(根据电脑配置不同休眠时间自己调整)。

public class Ticket implements Runnable {
int num = 10;
@Override
public void run() {
while (true) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(num>0){
num--;
System.out.println(Thread.currentThread().getName() + ":" + num);
}
}
}
}


Thread-0:9
Thread-1:8
Thread-2:8
Thread-0:7
Thread-1:6
Thread-2:5
Thread-0:4
Thread-1:3
Thread-2:2
Thread-0:1
Thread-2:0
Thread-1:-1
Thread-0:-2

Process finished with exit code 0


安全问题:我们发现当睡眠200毫秒后程序出现了问题,我们多卖出了8,-1,-2 三张票。出现了安全问题。

原因:两个或以上数量的线程同时执行了相同的代码,同时卖出一样的票。导致同样的票买了两次或多次。

2.实现方式二(安全问题解决方案)

解决方案:同步锁

public class Ticket implements Runnable {
int num = 10;
Object object=new Object();
@Override
public void run() {
while (true) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (object){
if (num>0) {
num--;
System.out.println(Thread.currentThread().getName() + ":" + num);
}
}

}
}
}


现在我们的程序就可以成功运行了。

总结:

1.多线程存在线程安全问题。

2.可以用同步锁的方式解决同步问题。

3.线程安全问题产生的原因

1,多个线程在操作共享的数据。

2,操作共享数据的线程代码有多条。

解决思路;

就是将多条操作共享数据的线程代码封装起来,当有线程在执行这些代码的时候,

其他线程时不可以参与运算的。
必须要当前线程把这些代码都执行完毕后,其他线程才可以参与运算。

在java中,用同步代码块就可以解决这个问题。

同步代码块的格式:

synchronized(对象)

{

需要被同步的代码 ;

}

4.同步的好处和弊端

同步的好处:解决了线程的安全问题。

同步的弊端:相对降低了效率,因为同步外的线程的都会判断同步锁。

5.同步的前提:

同步中必须有多个线程并使用同一个锁。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: