java基础--多线程模拟买票案例---(同步)

Thread类中的构造方法和常用方法:
构造方法:public Thread() 和 public Thread(Runnable target)
常用方法:start() 开启线程 和 getName() 获取线程名字,线程名字的默认编号是Thread-编号,编号是默认从0开始 currentThread()是Thread的静态方法,获取当前线程对象

多线程安全问题:
概述:多线程并发操作统一数据,此时就有可能出现安全问题,此时需要使用同步来解决。

同步:进程进入了以后,进程没有执行执行完枷锁的代码块,剩下的进程都不能进入
同步代码块:

格式:
    synchronized(锁对象){
        要加锁的代码
    }
    1、同步代码块的锁对象可以是任意类型的对象
    2、必须使用同一把锁,不然会出现锁不住的情况
       此时我们会把锁对象设置为当前的字节码文件,
       因为无论哪一个,其对应的字节码文件只有一份

同步方法:—具体写入到这里了,哈哈哈>>>>有关同步方法具体相关点击这里
非静态同步方法:锁对象是this
静态同步方法:锁对象是该类的字节码文件对象(该类名.class)

线程安全,效率会低。

案例代码:

package thread;

public class ThreadTickts {

    public static void main(String[] args) {
        //创建多个线程
        MyThread1 mt1 = new MyThread1("窗口1");
        MyThread1 mt2 = new MyThread1("窗口2");
        MyThread1 mt3 = new MyThread1("窗口3");
        MyThread1 mt4 = new MyThread1("窗口4");
        mt1.start();
        mt2.start();
        mt3.start();
        mt4.start();
    }

}
/*
 * 出现安全问题,票数大时,出现的概率大,所以这里加入线程休眠来模拟出现问题的情况
 *      票数出现负值:当票数为1的时候,刚好窗口1-4都是休眠状态,此时休眠结束后,直接往下执行
 *              此时已经跳过了if判断,所以窗口1-4都会继续输出
 *    票数出现重复值:问题出现在tickts--,因为有可能在tickts-1的时候,cpu资源被别人抢走
 *              此时tickts虽然-1,但是却没有重新赋给tickts
 * 
 */
class MyThread1 extends Thread{
    //切记,此时的tickts一定要定义为static的,即是四个窗口共享100张票
    //如果没有定义为static,则会每个窗口都会分别出售100张票
    static int tickts=100;

    public MyThread1() {
        super();
    }

    public MyThread1(String name) {
        super(name);
    }

    @Override
    public void run() {

        while(true){
            synchronized (ThreadTickts.class) {
                if(tickts<1){
                    break;
                }
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(getName()+"----正在卖"+ tickts-- +"张票");
            }
        }

    }
}

方式二案例:

package thread;

public class ThreadTickts2 {
    public static void main(String[] args) {
        //创建Runnable接口的子类对象
        MyRunnable1 mr = new MyRunnable1();
        //创建线程对象
        Thread th1 = new Thread (mr,"窗口1");
        Thread th2 = new Thread (mr,"窗口2");
        Thread th3 = new Thread (mr,"窗口3");
        Thread th4 = new Thread (mr,"窗口4");
        th1.start();
        th2.start();
        th3.start();
        th4.start();
    }
}

class MyRunnable1 implements Runnable{
    //此时不需要加static,因为Runnable接口的子类对象只创建一个
    int tickts=100;
    //构造方法也不用重写,因为开启的线程对象就是Thread,
    //不像继承Thread方式那样去调用父类的构造
    @Override
    public void run() {

        while(true){
            synchronized (ThreadTickts.class) {
                if(tickts<1){
                    break;
                }
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //currentThread()是Thread的静态方法,获取当前线程对象
                System.out.println(Thread.currentThread().getName()+"----正在卖"+ tickts-- +"张票");
            }
        }

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值