线程同步机制和互斥锁

1.在多线程编程,一些敏感数据不允许被多个绒程同时访问,此时就使用同步访问术,保证数据在任何同一时刻,最多有一个线程访问,以保证数据的完整性。
2.也可以这里理解:线程同步,即当有一个线程在对内存进行操作时,其他线程都可以对这个内存地址进行操作,直到该线程完成操作,其他线程才能对该内存地址进行操作.

线程同步机制的使用

在这里插入图片描述

互斥锁

1.Java语言中,引入了对象互斥锁的概念,来保证共享数据操作的完整性。
2.每个对象都对应于一个可称为“互斥锁”的标记,这个标记用来保证在能有一个线程访问该对象。
3.关键字synchronized 来与对象的互斥锁联系。当某个对象用synchronized
表明该对象在任一时刻只能由一个线程访问
4.同步的局限性:导致程序的执行效率要降低
5.同步方法(非静态的)的锁可以是this,也可以是其他对象(要求是同一个对象)
6.同步方法(静态的)的锁为当前类本身。’

使用互斥锁来解决售票问题

给代码块加锁

package program;

public class SellTicket2 {
    public static void main(String[] args) {
        Thread thread = new Tickets();
        thread.start();

        Thread thread2 = new Tickets();
        thread2.start();

        Thread thread3 = new Tickets();
        thread3.start();
    }
}

class Tickets extends Thread {
    private static int tickets = 100;
    private boolean loop = true;
    //方式一 代码块加锁
   public  void sell() {
       synchronized (this) {
           if (tickets <= 0){
               System.out.println("售票结束");
               loop = false;
               return;
           }

           try {
               Thread.sleep(50);//休眠50毫秒
           } catch (Exception e) {
               throw new RuntimeException(e);
           }
           System.out.println(Thread.currentThread().getName() + "售出了一张票,剩余票数:" + (--tickets));
       }
   }
    @Override
    public void run() {
        while (loop) {
            sell();

        }
    }

}

运行结果

在这里插入图片描述

给方法加锁

package program;
/**
 * @Author 雾潋
 * @Version 1.0
 * 使用多线程,模拟三个窗口同时售票 100 张
 */
@SuppressWarnings("all")
public class SellTicket {
    public static void main(String[] args) {
        Ticket ticket = new Ticket();
        Thread thread = new Thread(ticket);
        thread.start();//线程一

        Ticket ticket1 = new Ticket();
        Thread thread1 = new Thread(ticket1);
        thread1.start();//线程二
        ticket1.setLoop(false);
        Ticket ticket2 = new Ticket();
        Thread thread2 = new Thread(ticket2);
        thread2.start();//线程三


        /*//方式二
        Ticket2 ticket21 = new Ticket2();
        ticket21.start();
        Ticket2 ticket22 = new Ticket2();
        ticket22.start();
        Ticket2 ticket23 = new Ticket2();
        ticket23.start();*/
    }
}

//方法一
class Ticket implements Runnable{
    public static int tickets = 100;
    private boolean  loop = true; //用于主线程控制子线程退出
    public synchronized void f() { //同步方法,在同一时刻,只有一个线程来执行f()方法
        if (tickets <= 0) {
            System.out.println("售票结束");
            loop = false;
            return;
        }
        try {
            Thread.sleep(50);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println("窗口" + Thread.currentThread().getName() + "售出一张票" + ",剩余票数:" + (--tickets));
    }

    @Override
    public   void run() {
       while (loop){
           f();
       }

    }
    public boolean isLoop() {
        return loop;
    }

    public void setLoop(boolean loop) {
        this.loop = loop;
    }
}

给类加锁

package program;

public class SellTicket2 {
    public static void main(String[] args) {
        Thread thread = new Tickets();
        thread.start();

        Thread thread2 = new Tickets();
        thread2.start();

        Thread thread3 = new Tickets();
        thread3.start();
    }
}

class Tickets extends Thread {
    private static int tickets = 100;
    private boolean loop = true;
    //方式一 代码块加锁
   public  void sell() {
       synchronized (SellTicket2.class) {
           if (tickets <= 0){
               System.out.println("售票结束");
               loop = false;
               return;
           }

           try {
               Thread.sleep(50);//休眠50毫秒
           } catch (Exception e) {
               throw new RuntimeException(e);
           }
           System.out.println(Thread.currentThread().getName() + "售出了一张票,剩余票数:" + (--tickets));
       }
   }
    @Override
    public void run() {
        while (loop) {
            sell();

        }
    }

}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值