多线程售票


//测试 多线程售票
//1, 需求: 设计4个售票窗口,总计售票100张。
public class C1 {
public static void main(String[] args) {
//TODO 问题1 : 总共要卖100张,如今卖了400张,为何??
// 缘由是:int tickets=100;是成员变量,是每一个对象初始化都要存储的,四个对象存了四份.
// 怎么解决 --想办法让成员变量变成 多个对象间共享的资源,保证全局惟一
MyTickets t = new MyTickets();
MyTickets t2 = new MyTickets();
MyTickets t3 = new MyTickets();
MyTickets t4 = new MyTickets();

t.start();
t2.start();
t3.start();
t4.start();
}
}
//方式1:: extends Thread
class MyTickets extends Thread{
//TODO 问题1 :加上static 把票变成共享资源,而不是人手一份
static int tickets = 100 ;//定义变量,记录票数
//准备卖票,,把业务放入重写的run()
@Override
public void run(){
while(true){
if(tickets >0){
//TODO 考验,多线程编程中的数据到底安全不???--sleep()
try{
//TODO 问题2: 重卖--出现同一张票卖给了多我的
//TODO 问题3: 超卖--卖出了0 -1 -2号票
//TODO 缘由???
Thread.sleep(10);
}catch (InterruptedException e){
e.printStackTrace();
}

System.out.println(super.getName()+"--"+tickets--);
}else{
break;//专门用来结束 死循环 !!
}
}

}
}


//方式2:: implements Runnable
class Ticket implements Runnable{
int ticket = 100;
@Override
public void run() {
while (true){
if(ticket>0){
try {
//TODO 问题2: 重卖--出现同一张票卖给了多我的
//TODO 问题3: 超卖--卖出了0 -1 -2号票
//TODO 缘由???
//重卖的缘由:tickets=80 ,t1 t2 t3 t4 都开始准备卖票 ,
//超卖的缘由:tickets=1 ,t1 t2 t3 t4 都开始准备卖票 ,
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
//超卖的缘由:
//假设t1先醒,开始卖票,执行tickets--,输出1,自减变成0
//假设t2醒了,开始卖票,执行tickets--,输出0,自减变成-1
//假设t3醒了,开始卖票,执行tickets--,输出-1,自减变成-2
//假设t4醒了,开始卖票,执行tickets--,输出-2,自减变成-3

//重卖的缘由:
//假设t1先醒,开始卖票,执行tickets--,输出80 没来得及变
//假设t2醒了,开始卖票,执行tickets--,输出80 没来得及变
//假设t3醒了,开始卖票,执行tickets--,输出80 自减变成79
//假设t4醒了,开始卖票,执行tickets--,输出79....
System.out.println(Thread.currentThread().getName()+"--"+ticket--);
}else {
break;
}
}
}
}


用同步锁改进上面程序
public class C2 {
public static void main(String[] args) {
Ticket target = new Ticket();
Thread t = new Thread(target);
Thread t2 = new Thread(target);
Thread t3 = new Thread(target);
Thread t4 = new Thread(target);

t.start();
t2.start();
t3.start();
t4.start();
}
}

同步速方式2:: implements Runnable
class Ticket implements Runnable{
int ticket = 100;
Object o = new Object();
String s ="13";
@Override
//TODO 1,如今因为多线程 中,,对于共享资源进行了抢的操做,因此共享资源不安全
//能够使用锁 来保证安全,可是牺牲性能.synchronized表示锁
//锁能够用在方法上也能够用在代码块上.
//同步方法 synchronized public void run() {
//同步代码块 -- synchronized(锁对象){有问题代码}
public void run() {
while (true){
//TODO 2,同步代码块:须要考虑两个问题
//1,锁的位置(合理位置,从开始用到用完结束) 2,锁对象(能够任务,但必须是同一个对象)
//synchronized(new Object()){//四个线程new了4把锁,不是同一个锁对象,错的
//synchronized(o){//同一个锁对象,OK
//synchronized(s){//同一个锁对象,OK
synchronized (this) {
if (ticket > 0) {
try {

Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "--" + ticket--);
} else {
break;
}
}
}
}
}public class C1 {
    public static void main(String[] args) {
//TODO 问题1 : 总共要卖100张,如今卖了400张,为何??
// 缘由是:int tickets=100;是成员变量,是每一个对象初始化都要存储的,四个对象存了四份.
// 怎么解决 --想办法让成员变量变成 多个对象间共享的资源,保证全局惟一
MyTickets t = new MyTickets();
MyTickets t2 = new MyTickets();
MyTickets t3 = new MyTickets();
MyTickets t4 = new MyTickets();

t.start();
t2.start();
t3.start();
t4.start();
}
}


同步锁改进方式1:: extends Thread
class MyTickets extends Thread{
//TODO 问题1 :加上static 把票变成共享资源,而不是人手一份
static int tickets = 100 ;//定义变量,记录票数
//准备卖票,,把业务放入重写的run()
@Override
//TODO 3,方法被同步后,会自动分配锁对象.普通方法的锁对象默认是this
//静态方法的锁对象才是 类名.class
// synchronized public void run() {
public void run(){
while(true){
//TODO 1,锁对象怎么分配 -- 看你的共享资源是普通仍是静态的
//TODO 2,静态资源的 锁对象 必须是类名.class synchronized (MyTickets.class) { if (tickets > 0) { try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(super.getName() + "--" + tickets--); } else { break;//专门用来结束 死循环 !! } } } }}
相关文章
相关标签/搜索