线程深入理解
- 线程对象只能启动一个线程。不管是继承Thread,还是通过实现Runnable接口创建线程,它们的一个对象只能启动(即start())一次,否则就会有异常抛出。不能通过此方式实现多个线程跑起来。
问题:模拟一个机票售票系统,有三个售票点,在一天内卖出2000张票,(一共卖出2000张)。
这里要考虑,多线程并发会带来线程安全问题。本题中,有可能会出现同一张票被卖了多次。
如何解决?
解决问题的关键就是要保证容易出问题代码的原子性,所谓的原子性就是指:当a
线程在执行某段代码的时候,别的线程必须等到a线程执行完后,它才能执行这段代码。
java处理的方法就是在需要同步的代码段用下列包起来:
synchronized(Object){
//你需要同步的代码
}
当某个线程在处理某段被同步的代码时,其他的线程就会被blocked,放入线程等待池。
package com.chen;
public class SellTickets {
public static void main(String[] args) {
TicketWindow window = new TicketWindow();
Thread t1 = new Thread(window);
Thread t2 = new Thread(window);
Thread t3 = new Thread(window);
t1.start();
t2.start();
t3.start();
}
}
class TicketWindow implements Runnable{
private int nums = 2000;
public void run() {
while(true){
//这段要保证原子性
synchronized(this){
if(this.nums > 0){
System.out.println(Thread.currentThread().getName() + "正在销售第"+this.nums+"张票");
try {
Thread.sleep(700);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.nums--;
}else{
break;
}
}
}
}
}