25/365 java 守护线程 线程同步 synchronized

news2024/11/15 17:20:28

1.守护线程

线程分为守护线程和用户线程  : daemon thread and non-daemon thread

虚拟机必须等待用户线程执行完毕,但无需等待守护线程执行完毕。

守护线程举例:垃圾回收线程,监控内存线程。

setDaemon(true):默认为false,默认为用户线程

public class D19 {
    public static void main(String[] args) {
        Thread thread = new Thread(new A1());
        thread.setDaemon(true);

        thread.start();

        new Thread(new A2()).start();
    }
}

class A1 implements Runnable{
    @Override
    public void run() {
        while(true){
            System.out.println("This is a daemon thread.");
        }
    }
}

class A2 implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("This is a non-daemon thread.");
        }
        System.out.println("The non-daemon thread has finished.");
    }
}

A1并没有设置停止条件,但因为将它设置为了守护线程,所以程序可以正常结束。

2.线程同步

并发:多个线程操作一个对象

当多个线程操作同一个对象,并且有线程想要修改该对象时,就会出现线程同步的问题。

线程同步是一种等待机制,多个线程进入该对象的等待池形成队列,等待前一个线程使用完毕,下一个线程再使用。

使用线程和锁来保证线程同步的安全性。

锁机制:当一个线程获得锁,独占资源,其他线程必须等待,直到该线程使用完毕,释放锁。

问题:

  • 等待该资源的对象挂起
  • 加锁,释放锁导致更多的开销:上下文切换,调度延时
  • 优先级倒置

3.运用synchronized关键字解决线程并发造成的不安全问题

1)synchronized关键字修饰方法,默认锁的是该方法的对象

使用前:

import org.omg.CORBA.TIMEOUT;

public class D20 {

    public static void main(String[] args) {
        Ticket ticket = new Ticket();
        new Thread(ticket).start();
        new Thread(ticket).start();
        new Thread(ticket).start();
        new Thread(ticket).start();


    }
}

class Ticket implements Runnable{
    int ticketNum = 20;
    boolean flag = true;
    @Override
    public void run() {
        while(flag){
            try {
                buy();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }

    public  void buy() throws InterruptedException {
        if(ticketNum<=0){
            flag = false;
            return;
        }

        Thread.sleep(100);

        System.out.println(Thread.currentThread().getName()+" buy ticket: " + ticketNum--);
    }
}

不安全结果:多个对象取到相同的票

 加入synchronized关键字

import org.omg.CORBA.TIMEOUT;

public class D20 {

    public static void main(String[] args) {
        Ticket ticket = new Ticket();
        new Thread(ticket).start();
        new Thread(ticket).start();
        new Thread(ticket).start();
        new Thread(ticket).start();


    }
}

class Ticket implements Runnable{
    int ticketNum = 20;
    boolean flag = true;
    @Override
    public void run() {
        while(flag){
            try {
                buy();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }

    public synchronized void buy() throws InterruptedException {
        if(ticketNum<=0){
            flag = false;
            return;
        }

        Thread.sleep(100);

        System.out.println(Thread.currentThread().getName()+" buy ticket: " + ticketNum--);
    }
}

结果:不再出现取到同一张票的问题

2)用synchronized同步块

synchronized(Obj){ }

Obj为同步监视器,锁定代码块,同一时刻下只有一个线程访问该代码块

当synchronized修饰方法时,同步监视器默认为该方法的对象,也就是this

使用前:

import java.util.ArrayList;
import java.util.List;

public class D21 {
    public static void main(String[] args) throws InterruptedException {
        List<String> list = new ArrayList<String>();
        for(int i=0;i<10000;i++){
            new Thread(()->{

                    list.add(Thread.currentThread().getName());

            } ).start();
        }
        Thread.sleep(100);
        System.out.println(list.size());
    }
}

不安全结果:多个线程向同一个地址写入数据,导致list的size不足10000

加入synchronized修饰代码块

import java.util.ArrayList;
import java.util.List;

public class D21 {
    public static void main(String[] args) throws InterruptedException {
        List<String> list = new ArrayList<String>();
        for(int i=0;i<10000;i++){
            new Thread(()->{
                    synchronized (list) {
                        list.add(Thread.currentThread().getName());
                    }
            } ).start();
        }
        Thread.sleep(100);
        System.out.println(list.size());
    }
}

 结果:

java中有线程安全的ArrayList: CopyOnWriteArrayList

import java.util.concurrent.CopyOnWriteArrayList;

public class D22 {
    public static void main(String[] args) {
        CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();
        for (int i = 0; i < 10000; i++) {
            new Thread(
                    ()->{
                        list.add(Thread.currentThread().getName());
                    }
            ).start();
        }

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

        System.out.println(list.size());
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/176342.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【LeetCode:121. 买卖股票的最佳时机~~~动态规划】

题目描述 给定一个数组 prices &#xff0c;它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 你只能选择 某一天 买入这只股票&#xff0c;并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。 返回你可以从这笔交易中获取的…

【微信小程序】文章点赞功能的实现

&#x1f3c6;今日学习目标&#xff1a;第二十期——文章点赞功能的实现 ✨个人主页&#xff1a;颜颜yan_的个人主页 ⏰预计时间&#xff1a;15分钟 &#x1f389;专栏系列&#xff1a;我的第一个微信小程序 文章目录前言效果图实现步骤总结前言 哈喽大家好&#xff0c;本期是…

Unity简单几行代码让玩家水平移动更丝滑真实

可以先来看看基础的移动代码&#xff0c;接收玩家的输入&#xff0c;然后赋予刚体速度。 但是这种写法存在几个问题&#xff0c;下面一一纠正。 首先&#xff0c;如果直接改变刚体的速度&#xff0c;那么可能会出现穿墙的问题。 而且没有一种从速度0到缓慢加速的过程&#xff…

自定义Filter后,我的业务代码怎么被执行了多次?

若要求构建的过滤器针对全局路径有效&#xff0c;且无任何特殊需求&#xff08;主要针对 Servlet 3.0 的一些异步特性&#xff09;&#xff0c;则完全可直接使用 Filter 接口&#xff08;或继承 Spring 对 Filter 接口的包装类 OncePerRequestFilter&#xff09;&#xff0c;并…

分享130个ASP源码,总有一款适合您

ASP源码 分享130个ASP源码&#xff0c;总有一款适合您 下面是文件的名字&#xff0c;我放了一些图片&#xff0c;文章里不是所有的图主要是放不下...&#xff0c; 130个ASP源码下载链接&#xff1a;https://pan.baidu.com/s/13ZxaHPHdgorjGV1wWvx1WQ?pwd7z4p 提取码&#x…

07_FreeRTOS任务调度器的挂起和恢复

任务调度器的挂起和恢复 挂起任务调度器,调用此函数不需要关闭中断 使用格式示例: 1.与临界区不一样的是,挂起任务调度器,未关闭中断; 2.它仅仅是防止&#xff1b;饿任务之间的资源争夺,中断照样可以直接响应; 3.挂起调度器的方式,适合于临界区位于任务与任务之间;既不用去延…

MySQL 8.0.31 集合操作INTERSECT和EXCEPT

对于聚合的功能MySQL是都是默默的发展。在最新的8.0.31版本中提供对集合操作INTERSECT和EXCEPT。这样一来&#xff0c;集合操作功能基本圆满了。MySQL5.7.40版本是不支持这个集合的。 In this release MySQL adds support for the SQL standard INTERSECT and EXCEPT table op…

Linux常用命令——ssh命令

在线Linux命令查询工具(http://www.lzltool.com/LinuxCommand) ssh openssh套件中的客户端连接工具 补充说明 ssh命令是openssh套件中的客户端连接工具&#xff0c;可以给予ssh加密协议实现安全的远程登录服务器。 语法 ssh(选项)(参数)选项 -1&#xff1a;强制使用ssh协…

基于FPGA的时间数字转换(TDC)设计(四)

1. 基于IODELAY的TDC设计原理 在第一篇中讲过,基于FPGA开发的TDC常见的有直接计数法,多相位时钟采样法,抽头延迟线法等等。前面3篇讲解了基于多相位的TDC,接下来主要讲解基于抽头延迟线的方法。在Xilinx FPGA开发中,要实现抽头延迟线,主要由进位链(Carry4)和IODELAY模块…

寒假题练——day(6)

题目1&#xff1a; 有一种兔子&#xff0c;从出生后第3个月起每个月都生一只兔子&#xff0c; 小兔子长到第三个月后每个月又生一只兔子。 例子&#xff1a;假设一只兔子第3个月出生&#xff0c;那么它第5个月开始会每个月生一只兔子。 一月的时候有一只兔子&#xff0c;假如兔…

检索方案优化

文章目录 1. Flab框架概览2. Flab框架各个层在基金检索的具体应用2.1. 前置检查Check层2.2. 多路召回Recall层2.3. 结果集过滤2.3.1. 问财和我们召回结果的交集2.4. 排序Rank2.5. 缓存Cache2.6. 封装Assmeble1. Flab框架概览 Fly like a bird 寓意灵活 2. Flab框架各个层在基金…

2023年大年初一 —— 牛客网刷题经验分享~

2023年大年初一 —— 牛客网刷题经验分享~&#x1f60e;大年初一 —— 牛客网刷题经验分享~&#x1f60e;)前言&#x1f64c;BC94 反向输出一个四位数 &#x1f60a;BC95 小乐乐与进制转换 &#x1f60a;BC96 [NOIP2015]金币&#x1f60a;BC97 回文对称数 &#x1f60a;总结撒花…

pytorch 神经网络基础入门笔记【b站小土堆】

文章目录python深度学习配置环境anacondapycharmpytorchpython学习中的两大法宝函数加载数据Tensorboard使用torchvision中的transformstensor数据类型transform该如何使用为什么我们需要Tensor类型更好的使用transformsToTensorNormalizeResizeComposeRandomCrop总结torchvisi…

JVM快速入门学习笔记(三)

9. 栈 栈&#xff1a;8大基本类型对象引用 栈运行原理&#xff1a;栈帧 程序正在执行的方法&#xff0c;一定在栈的顶部 9.1 JVM数据区 先上一张Java虚拟机运行时数据区中堆、栈以及方法区存储数据的概要图&#xff0c;如下所示&#xff1a; 9.2 堆 堆是存储时的单位&…

美团出品 | YOLOv6 v3.0 is Coming(超越YOLOv7、v8)

&#x1f680;&#x1f680;&#x1f680;美团出品 | YOLOv6 v3.0 is Coming &#xff01;&#xff01;✨✨✨ 一、前言简介 &#x1f384;&#x1f388; &#x1f4da; 代码地址&#xff1a;美团出品 | YOLOv6 3.0代码下载地址 &#x1f4da; 文章地址&#xff1a;https://a…

四、python-pyecharts图表可视化(黑马程序猿-python学习记录)

黑马程序猿的python学习视频&#xff1a;https://www.bilibili.com/video/BV1qW4y1a7fU/ 目录 1. 官网链接 2. 下载pyecharts 3. 编写一个折线图 4. 隐藏线段上的数据 5. 绘制柱状图 6. 柱状图的xy轴反转 7. 柱状图设置提示在最右边 8. 时间柱状图 9. 时间柱状图设置颜色主题 …

第三章 AOP

1.AOP基本概念*什么是AOP&#xff1a;面向切面编程&#xff0c;利用AOP可以对业务逻辑的各个部分进行隔离&#xff0c;从而使得业务逻辑各个部分之间的耦合度降低&#xff0c;提高程序的可重用性&#xff0c;同时提高开发效率&#xff08;不通过修改源代码方式&#xff0c;在主…

深入跨域问题(2) - 利用 CORS 解决跨域

目录 1.搭建跨域环境(先展示一下跨域请求的情况)&#xff1a; 2.处理非预请求 3.处理 POST 预请求 4.总结&#xff1a; 1.搭建跨域环境(先展示一下跨域请求的情况)&#xff1a; 模拟客户端请求&#xff1a; <!DOCTYPE html> <html lang"zh-CN"> <…

客快物流大数据项目(一百零七):物流信息查询服务接口开发解决方案

文章目录 物流信息查询服务接口开发解决方案 一、业务需求