线程同步机制,互斥锁,释放锁

同步线程解决售票问题:

/**
 * @author WuYazhen
 * @Date 2024/8/7 10:42
 * 使用同步线程优化售票问题
 */
public class TicketSell {
    public static void main(String[] args) {
        TicketSell01 ticketSell01 = new TicketSell01();

        new Thread(ticketSell01).start();
        new Thread(ticketSell01).start();
        new Thread(ticketSell01).start();

    }
}


//实现接口方式,使用synchronized实现线程同步
class TicketSell01 implements Runnable{
    private static int ticketNum = 100;
    private boolean loop = true; //控制run方法while循环

    public synchronized void sell(){ //同步方法,在同一个时刻只能有一个线程来执行sell方法
        if (ticketNum <= 0){
            System.out.println("售票结束");
            loop = false;
            return;
        }
        try {
            Thread.sleep(50);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("窗口"+Thread.currentThread().getName()+"售出一张票,剩余票数:"+(--ticketNum));
    }
    @Override
    public void run() {
        while (loop){
            sell(); //sell方法是一个同步方法
        }
    }
}

线程死锁

死锁案例:

/**
 * @author WuYazhen
 * @Date 2024/8/10 10:28
 * 模拟死锁现象
 */
public class DeadLock {
    public static void main(String[] args) {
        //模拟死锁现象
        DeadLockDemo A = new DeadLockDemo(true);
        DeadLockDemo B = new DeadLockDemo(false);
        A.setName("A线程");
        B.setName("B线程");
        A.start();
        B.start();

    }
}

class DeadLockDemo extends Thread{
    static Object o1 = new Object();//保证多线程,共享一个对象,这里使用static
    static Object o2 = new Object();
    boolean flag;

    public DeadLockDemo(boolean flag){//构造器
        this.flag = flag;
    }
    @Override
    public void run() {
        /*
        * 业务逻辑分析:
        * 1,如果flag为t,线程A就会先得到o1对象锁,然后尝试去获取o2对象锁
        * 2,如果线程A得不到o2对象锁,就会Blocked
        * 3,如果flag为f,线程B就会先得到o2对象锁,然后尝试去获取o1对象锁
        * 4,如果线程B得不到o1对象锁,就会Blocked
        * */
        if (flag){
            synchronized (o1){//对象互斥锁
                System.out.println(Thread.currentThread().getName()+"进入1");
                synchronized (o2){
                    System.out.println(Thread.currentThread().getName()+"进入2");
                }

            }
        }else {
            synchronized (o2){
                System.out.println(Thread.currentThread().getName()+"进入3");
                synchronized (o1){ //这里获取li对象的监视权
                    System.out.println(Thread.currentThread().getName()+"进入4");
                }

            }

        }
    }
}

运行结果显示a,b进入死锁状态

线程练习作业:

package test;

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;
import java.util.Scanner;

/**
 * @author WuYazhen
 * @Date 2024/8/10 11:05
 * main中启动两个线程,一个循环随机打印100以内的整数,直到第二个线程从键盘读取了“q”命令
 */
public class ThreadHomework {
    public static void main(String[] args) {
        M1 m1 = new M1(true);
        M2 m2 = new M2(m1);
        m1.start();
        m2.start();
    }
}

class M1 extends Thread{
    private boolean b = true;

    public M1(boolean b) {
        this.b = b;
    }

    public void setB(boolean b) {
        this.b = b;
    }

    @Override
    public void run() {
        Random random = new Random();
        while(b){
            // 生成一个1到100之间的随机整数(包含1和100)
            int randomNumber = random.nextInt(100) + 1;

            // 打印这个随机整数
            System.out.println(randomNumber);
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }
}

class M2 extends Thread{
    private M1 m1;
    private Scanner scanner = new Scanner(System.in);

    public M2(M1 m1) {
        this.m1 = m1;
    }

    @Override
    public void run() {
        while(true){
            //接收到用户的输入
            System.out.println("请输入指令(Q表示退出):");
            char key =scanner.next().toUpperCase().charAt(0);
            if (key == 'Q'){
                //已通知的方式结束A线程
                m1.setB(false);
                System.out.println("M2线程退出");
                break;
            }
        }
    }
}

package test;

/**
 * @author WuYazhen
 * @Date 2024/8/11 23:38
 * 2个用户从一张10000元的卡上取钱,每次取1000,余额不足时无法取,不能出现超取现象
 * 线程同步问题
 */
public class ThreadHomework02 {
    public static void main(String[] args) {
        TakeMoney takeMoney = new TakeMoney();
        new Thread(takeMoney).start();
        new Thread(takeMoney).start();
    }
}

class TakeMoney implements Runnable{
    private static int sum = 10000;
    boolean loop = true;
    public synchronized void take(){
        if (sum >= 1000){
            sum-=1000;
            System.out.println(Thread.currentThread().getName()+"成功取钱,余额为:"+sum);
        }else {
            loop = false;
        }
    }

    @Override
    public void run() {
        while (loop){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            take();
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值