关于多线程安全问题的第一种解决方法( 同步代码块)


       问题原因:线程1还未执行完操作,后面线程却接种而来
      解决:必须保证一个线程a在操作ticket时,其它线程等待,直到a操作完成,其它线程才能继续操作
      方式1:同步代码块:synchornized(同步监视器(锁)){一般使用this
                                               //共享代码}其它线程得等待
      同步监视器可以 用任何一个类充当,但是多个线程必须共同使用一个监视器

关于多线程同时进行对某变量的同时操作时产生的安全问题
例如三个窗口共卖100张票,不可重复卖票,意即三个窗口共享一个票,采用接口实现类创建多线程
public class WindowTest {
    public static void main(String[] args) {
        //创建三个线程
        Ticket t= new Ticket();
        Thread t1 = new Thread(t);
        Thread t2 = new Thread(t);
        Thread t3 = new Thread(t);
        //分别给三个线程命名
        t1.setName("窗口1");
        t2.setName("窗口2");
        t3.setName("窗口3");
        t1.start();
        t2.start();
        t3.start();
        //但以上结果出现了3次100的票,采用继承方式也会存在安全问题(if语句)
    }
}
class Ticket implements Runnable{

    int ticket=100;
    Object obj =new Object();
    @Override
    public void run() {
        //int ticket = 100;如果定义在方法内部则会导致每一份对象都会有100张票
        while(true)//如果synchronized把while也包住了就不是多线程了
        {
            try {
                Thread.sleep(5);//加点延迟不然不行
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //synchronized (obj){//obj是唯一的
            synchronized (this){//或者Ticket.class
                //继承中的this不唯一
                // this是唯一的,在接口实现类下,因为this是指调用run方法的对象也就只是Ticket t= new Ticket();
                if(ticket>0)
                {
                    System.out.println(Thread.currentThread().getName()+":"+"第"+ticket+"张票售出");
                    ticket--;
                }
                else
                    break;
            }


        }
    }
}

-----------------------------------------下面是继承类的多线程解决-------------------------------------------

/*
*           采用继承类实现多线程
*           使用同步代码快解决安全问题synchronized
*           同步监视器慎用this关键看对象是否唯一
*
* */
public class window {
    public static void main(String[] args) {
        windows w1= new windows();
        windows w2= new windows();
        windows w3= new windows();
        w1.setName("窗口1");
        w2.setName("窗口2");
        w3.setName("窗口3");
        w1.start();
        w2.start();
        w3.start();
    }
}
class windows extends Thread{
    static int ticket=100;
    //static Object obj = new Object();//方式一
    public void run()
    {
        while(true)
        {
            //synchronized (this){//此处this 指w1,w2,w3
            //synchronized (obj){//使用obj静态
            synchronized (Window.class){//要放对象 Class clz = Window.class
                if(ticket>0)
                {
                    System.out.println(Thread.currentThread().getName()+":"+"第"+ticket+"张票售出");
                    ticket--;
                }
                else
                    break;
                }
        }
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值