1.线程并发的产生
这里举一个买票的经典案例:四个窗口售卖100涨车票,代码如下:
public class Ticket implements Runnable{
/**线程名称*/
private String name;
/**车票库存*/
static int tickets = 100;
/**构造器*/
public Ticket(String name){
this.name = name;
}
@Override
public void run(){
while (true){
if(tickets>0){
System.out.println(name+"窗口正在售卖第"+(tickets--)+"张票");
}else {
break;
}
}
System.out.println(name+"窗口售完票");
}
}
运行后发现存在多个窗口成功售卖同一张票,这样不符合实际需求的情况就是线程的并发。
2.线程并发的解决
使用synchronized关键字,语法如下:
synchronized(锁对象){
//操作共享资源的代码
}
同步代码加在什么地方?
(1)代码被多个线程访问;
(2)代码中有共享的数据;
(3)共享数据被多条语句操作;
修改买票案例,代码如下:
public class Ticket implements Runnable{
/**车票库存*/
int tickets = 100;
/**创建一个锁对象,这个对象有多个线程共同使用*/
static Object obj = new Object();
@Override
public void run(){
while (true){
//多线程共享代码块
synchronized (obj) {
if (tickets > 0) {
System.out.println(Thread.currentThread().getName() + "窗口正在售卖第" + (tickets--) + "票");
} else {
break;
}
}
}
System.out.println(Thread.currentThread().getName()+"窗口售完票");
}
public static void main(String args[]){
Ticket ticket = new Ticket();
Thread thread1 = new Thread(ticket,"窗口1");
Thread thread2 = new Thread(ticket,"窗口2");
Thread thread3 = new Thread(ticket,"窗口3");
Thread thread4 = new Thread(ticket,"窗口4");
thread1.start();
thread2.start();
thread3.start();
thread4.start();
}
}
*注意:本次改造把整个Ticket类作为了共享对象