【从入门到起飞】JavaSE—多线程(3)(生命周期,线程安全问题,同步方法)

🎊专栏【JavaSE】

🍔喜欢的诗句:路漫漫其修远兮,吾将上下而求索。

🎆音乐分享【如愿】

🎄欢迎并且感谢大家指出小吉的问题🥰

文章目录

🍔生命周期

🎄线程的安全问题

发现有两个问题,相同的票出现了多次,出现了超出范围的票

🏳️‍🌈原因

首先线程被线程一抢走了

线程一执行到了sleep,会休眠10ms,然后ticket+1,变为了1
然后线程被线程二抢走了

线程二执行到了sleep,会休眠10ms,然后ticket+1,变为了2
然后线程被线程三抢走了

线程三执行到了sleep,会休眠10ms,然后ticket+1,变为了3

现在ticket是3,就会打印3次ticket=3的结果
这就是重复票和超出范围的原因

⭐改进方法

我们把下面的代码给框起来,设置一个线程执行完这个代码块后,其他线程才能执行

🌺同步代码块

把操作共享数据的代码给锁起来

java 复制代码
synchronizd(锁){
	操作共享数据的代码
}
  • 锁默认打开,有一个线程进去了,锁自动关闭
  • 里面的代码全部执行完毕,线程出来,锁自动打开

我们把之前的代码块用锁包围起来康康效果如何

运行成功

MyThread.java

java 复制代码
public class MyThread extends Thread {

    //表示这个类的所有对象,都共享ticket数据
    static int ticket = 0;//0~99

    //锁的对象,一定要是唯一的
    static Object obj=new Object();

    @Override
    public void run() {
        while (true) {
            synchronized (obj) {
                if (ticket < 100) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    ticket++;
                    System.out.println(getName() + "正在卖第" + ticket + "张票");
                } else {
                    break;
                }
            }
        }
    }
}

Demo1.java

java 复制代码
package IODemo6;

public class Demo1 {
    public static void main(String[] args) throws InterruptedException {
        //创建线程对象
        MyThread t1=new MyThread();
        MyThread t2=new MyThread();
        MyThread t3=new MyThread();

        //起名字
        t1.setName("窗口一");
        t2.setName("窗口二");
        t3.setName("窗口三");

        //开启线程
        t1.start();
        t2.start();
        t3.start();
    }
}

⭐细节

  1. 锁必须要写到循环里面
  2. 锁对象必须唯一

🌺同步方法

就是把synchronized关键字加到方法上

java 复制代码
修饰符 synchronized 返回值类型 方法名(方法参数){
	......
}

MyRunnable.java

java 复制代码
public class MyRunnable implements Runnable{
    int ticket=0;

    @Override
    public void run() {
        while (true){
            //同步方法
            if (method()) break;
        }
    }

    public synchronized boolean method(){
        //共享数据 到了末尾
        if (ticket==100){
            return true;
        }else {
            //共享数据 没有到末尾
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            ticket++;
            System.out.println(Thread.currentThread().getName()+"在卖第"+ticket+"张票!!!");
        }
        return false;
    }
}

ThreadDemo.java

java 复制代码
public class ThreadDemo {
    public static void main(String[] args) {
        MyRunnable mr=new MyRunnable();

        Thread t1=new Thread(mr);
        Thread t2=new Thread(mr);
        Thread t3=new Thread(mr);

        t1.setName("窗口1");
        t2.setName("窗口2");
        t3.setName("窗口3");

        t1.start();
        t2.start();
        t3.start();
    }
}

如果大家有不明白的知识点,欢迎在评论区进行讨论

相关推荐
AI进化营-智能译站3 小时前
ROS2 C++开发系列17-多线程驱动多传感器|chrono高精度计时实现机器人同步控制
java·c++·ai·机器人
天若有情6736 小时前
程序员原创|借鉴JS事件冒泡,根治电脑文件混乱的“冒泡整理法”
开发语言·javascript·windows·ecmascript·电脑·办公·日常
qq_589568106 小时前
springbootweb案例,出现访问 http://localhost:8080/list 一直处于浏览器运转阶段
java·网络协议·http·list·springboot
JAVA面经实录9177 小时前
计算机基础(完整版·超详细可背诵)
java·linux·数据结构·算法
特种加菲猫7 小时前
继承,一场跨越时空的对话
开发语言·c++
AC赳赳老秦7 小时前
知识产权辅助:用 OpenClaw 批量生成专利交底书 / 软著申请材料,自动校验格式与内容合规性
java·人工智能·python·算法·elasticsearch·deepseek·openclaw
FYKJ_20108 小时前
springboot校园兼职平台--附源码02041
java·javascript·spring boot·python·eclipse·django·php
玩转单片机与嵌入式8 小时前
玩转边缘AI(TInyML):需要掌握的C++知识汇总!
开发语言·c++·人工智能
茉莉玫瑰花茶8 小时前
Qt 信号与槽 [ 1 ]
开发语言·数据库·qt