【从入门到起飞】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();
    }
}

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

相关推荐
Dola_Pan18 分钟前
Linux文件IO(二)-文件操作使用详解
java·linux·服务器
wang_book21 分钟前
Gitlab学习(007 gitlab项目操作)
java·运维·git·学习·spring·gitlab
AI原吾43 分钟前
掌握Python-uinput:打造你的输入设备控制大师
开发语言·python·apython-uinput
机器视觉知识推荐、就业指导43 分钟前
Qt/C++事件过滤器与控件响应重写的使用、场景的不同
开发语言·数据库·c++·qt
毕设木哥1 小时前
25届计算机专业毕设选题推荐-基于python的二手电子设备交易平台【源码+文档+讲解】
开发语言·python·计算机·django·毕业设计·课程设计·毕设
珞瑜·1 小时前
Matlab R2024B软件安装教程
开发语言·matlab
weixin_455446171 小时前
Python学习的主要知识框架
开发语言·python·学习
孤寂大仙v1 小时前
【C++】STL----list常见用法
开发语言·c++·list
蜗牛^^O^1 小时前
Docker和K8S
java·docker·kubernetes
她似晚风般温柔7892 小时前
Uniapp + Vue3 + Vite +Uview + Pinia 分商家实现购物车功能(最新附源码保姆级)
开发语言·javascript·uni-app