Java基础之多线程(三)4月打卡day10

举报
java厂长 发表于 2022/04/10 21:04:32 2022/04/10
【摘要】 Java基础之多线程(三)4月打卡day10关于作者作者介绍🍓 博客主页:作者主页🍓 简介:JAVA领域优质创作者🥇、一名在校大三学生🎓、在校期间参加各种省赛、国赛,斩获一系列荣誉🏆。🍓 关注我:关注我学习资料、文档下载统统都有,每日定时更新文章,励志做一名JAVA资深程序猿👨‍💻。1、多线程要使用多线程必须有一个前提,有一个线程的执行主类。从多线程开始,Java正式进入到应...

Java基础之多线程(三)4月打卡day10

关于作者

  • 作者介绍


🍓 博客主页:作者主页

🍓 简介:JAVA领域优质创作者🥇、一名在校大三学生🎓、在校期间参加各种省赛、国赛,斩获一系列荣誉🏆。

🍓 关注我:关注我学习资料、文档下载统统都有,每日定时更新文章,励志做一名JAVA资深程序猿👨‍💻。

1、多线程

要使用多线程必须有一个前提,有一个线程的执行主类。从多线程开始,Java正式进入到应用部分,而对于多线程的开发,从JavaEE上表现的并不是特别多,但是在Android开发之中使用较多,并且需要提醒的是,鄙视面试的过程之中,多线程所问道的问题是最多的。

1.11 线程的同步与死锁

所谓的同步问题是指多个线程操作统一次元所带来的信息安全性问题,

下面模拟一个简单的卖票程序,要求有3个线程,卖10张票。

image-20210816180351233

package com.day12.demo;
class MyTicket implements Runnable{
    private int ticket = 10;
    public void run(){
        for (int i = 0; i < 20; i++) {
            if(ticket > 0){
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "买票 =" + this.ticket--);
            }
            
        }
    }
}
public class TicketDemo {
    public static void main(String[] args) {
        MyTicket mt = new MyTicket();
        new Thread(mt,"票贩子A").start();
        new Thread(mt,"票贩子B").start();
        new Thread(mt,"票贩子C").start();
        
    }
}

运行上面程序发现,票数为0或者为负数,这种操作我们称为不同步操作。

image-20210816181053613

不同步的唯一好处就是处理速度快(多个线程并发执行),而去银行是一个业务员对应一个客户,这个速度必然很慢。数据的不同步对于访问是不安全的操作。

同步是指所有的线程不是一起进入方法中执行,而是一个一个进来执行。

image-20210816181431244

如果要写实现这把锁的功能,那么可以使用synchronized关键字进行处理,有两种处理模式:同步代码块、同步方法。

同步代码块

如果要使用这种情况必须设置一个要锁定当前对象

package com.day12.demo;
class MyTicket implements Runnable{
    private int ticket = 2000;
    public void run(){
        for (int i = 0; i < 1000; i++) {
            //在同一时刻,只允许一个线程进入并且操作,其他线程需要等待
            synchronized(this){//线程的逻辑锁
                if(ticket > 0){
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + "买票 =" + this.ticket--);
                }
            }
            
        }
    }
}
public class TicketDemo {
    public static void main(String[] args) {
        MyTicket mt = new MyTicket();
        Thread thread1 = new Thread(mt,"票贩子A");
        thread1.setPriority(Thread.MIN_PRIORITY);
        thread1.start();
        new Thread(mt,"票贩子B").start();
        new Thread(mt,"票贩子C").start();
        
    }
}

同步方法

package com.day12.demo;
class MyTicket implements Runnable{
    private int ticket = 2000;
    public void run(){
        for (int i = 0; i < 1000; i++) {
            //在同一时刻,只允许一个线程进入并且操作,其他线程需要等待
            synchronized(this){//线程的逻辑锁
                this.sale();
            }
        }
    }
    public synchronized void sale(){
        if(ticket > 0){
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } 
            System.out.println(Thread.currentThread().getName() + "买票 =" + this.ticket--);
        }
    }
}
public class TicketDemo {
    public static void main(String[] args) {
        MyTicket mt = new MyTicket();
        Thread thread1 = new Thread(mt,"票贩子A");
        thread1.setPriority(Thread.MIN_PRIORITY);
        thread1.start();
        new Thread(mt,"票贩子B").start();
        new Thread(mt,"票贩子C").start();
        
    }
}

同步虽然可以保证数据的完整性(线程安全操作),但是其执行的速度很慢。

1.12 死锁

一个线程执行完毕后才可以继续执行,但是如果现在相关的几个线程,彼此几个线程都在等待(同步),那么就会造成死锁。

image-20210816185434363

模拟死锁程序

package com.day12.demo;
class JieFei{
    public synchronized void say(Person Person){
        System.out.println("给钱放人");
        Person.get();
    }
    public synchronized void get(){
        System.out.println("得到钱");
    }
}
class Person{
    public synchronized void say(JieFei jiefei){
        System.out.println("放人就给钱");
        jiefei.get();
    }
    public synchronized void get(){
        System.out.println("得到人");
    }
}
public class DeadLock implements Runnable {
    JieFei jie = new JieFei();
    Person person = new Person();
    public static void main(String[] args) {
        // TODO 自动生成的方法存根
        new DeadLock(); 
    }
    public DeadLock(){
        new Thread(this).start();
        jie.say(person);
    }
    @Override
    public void run() {
        // TODO 自动生成的方法存根
        person.say(jie);
    }
}

死锁实在日后多线程程序开发之中经常会遇见问题,而以上的代码并没有任何实际意义,大概可以理解死锁的操作形式就可以了,不用去研究程序。记住一句话:数据要想完整操作必须使用同步,但是过多的同步会造成死锁。

面试题:请问多线程操作统一资源的时候要考虑到那些,会带来的问题?

多线程访问统一资源的时候一定要考虑同步的问题,但是过多的同步会带来死锁。

# 后语

厂长写博客目的初衷很简单,希望大家在学习的过程中少走弯路,多学一些东西,对自己有帮助的留下你的赞赞👍或者关注➕都是对我最大的支持,你的关注和点赞给厂长每天更文的动力。

对文章其中一部分不理解,都可以评论区回复我,我们来一起讨论,共同学习,一起进步!

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。