Java / Android 多线程和 synchroized 锁

news2024/10/7 12:19:50

s

AsyncTask 在Android R中标注了废弃 

synchronized 同步

Thread:

thread.start()

 public synchronized void start() {
        /**
         * This method is not invoked for the main method thread or "system"
         * group threads created/set up by the VM. Any new functionality added
         * to this method in the future may have to also be added to the VM.
         *
         * A zero status value corresponds to state "NEW".
         */
        if (threadStatus != 0)
            throw new IllegalThreadStateException();

        /* Notify the group that this thread is about to be started
         * so that it can be added to the group's list of threads
         * and the group's unstarted count can be decremented. */
        group.add(this);

        boolean started = false;
        try {
            start0();
            started = true;
        } finally {
            try {
                if (!started) {
                    group.threadStartFailed(this);
                }
            } catch (Throwable ignore) {
                /* do nothing. If start0 threw a Throwable then
                  it will be passed up the call stack */
            }
        }
    }

    private native void start0();

start0 是个native方法

进程和线程 进程> 线程

进程= 操作系统独立区域 ,可以有多条线程

进程和线程可以进行并行工作,线程依赖进程

Runable: 接口 重写run

new Thread(runnable)

thread.start(runnable)  runnable在Thread内部标为target

相比于thread,runnable可以重用 : Thread1(runnable),Thread2(runnable)

ThreadFactory: Thread 工厂方法
  private static void threadFactory() {
        AtomicInteger count = new AtomicInteger(0);
        ThreadFactory factory = new ThreadFactory() {
            @Override
            public Thread newThread(Runnable r) {
                return new Thread(r,"Thread-"+count.incrementAndGet());
            }
        };
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName());
            }
        };

        Thread thread = factory.newThread(runnable);
        thread.start();

        Thread thread1 = factory.newThread(runnable);
        thread1.start();
    }

Executor: 接口

   private static void executor() {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println("runnable run");
            }
        };
        Executor executor = Executors.newCachedThreadPool();
        executor.execute(runnable);
        executor.execute(runnable);
        executor.execute(runnable);
    }
public interface Executor {

    /**
     * Executes the given command at some time in the future.  The command
     * may execute in a new thread, in a pooled thread, or in the calling
     * thread, at the discretion of the {@code Executor} implementation.
     *
     * @param command the runnable task
     * @throws RejectedExecutionException if this task cannot be
     * accepted for execution
     * @throws NullPointerException if command is null
     */
    void execute(Runnable command);
}

newCachedThreadPool 返回 ExecutorService

void shutdown(); //关闭任务
List<Runnable> shutdownNow();//立即关闭 但是会调用intrat 用这个是安全的

  public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }

内部创建线程池,和连接池一样. 包含了线程的创建 销毁等操作 (0 //默认大小,当超过最大值Integer.MAX_VALUE,就会销毁到默认大小)

60L, TimeUnit.SECONDS,线程等待回收时间
 new SynchronousQueue<Runnable>() 创建队列

Executor executor1 = Executors.newSingleThreadExecutor();创建1个线程
   public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }
  public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }

newFixedThreadPool 创建固定数量的线程,不推荐,如果用得少或者不用也会是这么多,而且不可扩展更多,用来处理多个集中任务

newScheduledThreadPool:可以添加延迟
  public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
        return new ScheduledThreadPoolExecutor(corePoolSize);
    }
Callable:有返回值的Runnable ,方法 call : Type

  private static void callable() {
        Callable<String> callable = new Callable<String>() {
            @Override
            public String call() throws Exception {
                return "666";
            }
        };
        ExecutorService executorService = Executors.newCachedThreadPool();
        Future<String> future = executorService.submit(callable); //后台任务Future 否则就会阻塞主线程  execure则会阻塞进行等待
        try {
            String result = future.get(); //阻塞进行取值,
            System.out.println(result);
        } catch (ExecutionException | InterruptedException e) {
            throw new RuntimeException(e);
        }

    }

  if (future.isDone()){
            //如果完成任务
        }

流程图

线程同步:

public class SynchronizedDemo1 implements TestDemo{
    private boolean running =true;
    private void stop(){
        running = false;
    }

    @Override
    public void runTest() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                int round = 1;
                while (running){

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

看出会等待1秒然后跳出循环,但是实际上会一直执行 

每个线程都有一块独立的区域,会把变量copy,然后改变值,然后再传回去

但是如果是多线程,copy同一个值,进行修改,数据会乱

可以使用 volatile ,改变其内存可见性,同步

多线程中如若用

x++; 则会进行两步 1 int temp = x+1, 2  x = temp 不是原子操作

需要使用 synchronized 有线程调用则其他线程等待

private synchronized void count(){
    x++; 
}

AtomicInteger = int 的包装 增加原子性和同步性

AtomicInteger count = new AtomicInteger(0); //int
   AtomicInteger count = new AtomicInteger(0); //int
        ThreadFactory factory = new ThreadFactory() {
            @Override
            public Thread newThread(Runnable r) {
                return new Thread(r,"Thread-"+count.incrementAndGet()); //++count
               // count.getAndIncrement() //count++
            }
        };
AtomicBoolean
    private AtomicBoolean running = new AtomicBoolean(true);
         running.set(false);
            running.get()

除此之外还有

//同一个类如果有多个synchronized 一般就是有一个监视器 monitor 进行控制,只能由一个线程调用

可以再方法内部加上

synchronized (this){用当前监视器

}

synchronized在方法上会同步锁多个方法,仅供当前线程调用

public class SynchronizedDemo3 implements TestDemo{

    private int x= 0;
    private int y = 0;
    private String name;
    private Object monitor1 = new Object();
    private Object monitor2 = new Object();
    private synchronized void count(int newValue){
       synchronized (monitor1){
           x = newValue;
           y = newValue;
       }
    }

    private void  minus(int delta){
        synchronized (monitor1){
            x -= delta;
            y -= delta;
        }

    }

    //synchronized 锁住当前方法
    private synchronized void setName(String name){
        synchronized (monitor2){
            this.name = name;
        }

    }


    @Override
    public void runTest() {

    }
}

synchronized 在方法上等同于在内部的 synchronized (this)

synchronized 作用 = 同步性,互斥

死锁:多线程中,当前线程持有的锁,但拿不到需要进行执行代码中的锁,会一直等待

乐观锁 写入时先读取, 悲观锁 -读之前加锁,写入前加锁, 主要用于数据库

static 修饰的方法 用synchronized在方法上 等同于 在方法内部( synchronized (name.class))

用当前类当做锁

单例模式双重检查锁 写法1

ReentrantLock 可重入锁 需要手动加解锁,同时也要注意是否能够正常解锁

可以使用读写锁

 private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
    Lock readLock = lock.readLock();
    Lock writeLock = lock.writeLock();

线程安全本质是多个线程访问共同资源,在写入时,其他线程干预了,导致数据错误

锁机制是:对资源进行访问的一种限制

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

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

相关文章

Visual Interpretability for Deep Learning: a Survey

Visual Interpretability for Deep Learning: a Survey----《深度学习的视觉可解释性:综述》 摘要 本文回顾了最近在理解神经网络表示以及学习具有可解释性/解耦的中间层表示的神经网络方面的研究。尽管深度神经网络在各种任务中表现出了优越的性能&#xff0c;但可解释性始终…

基于SpringBoot+Vue+uniapp微信小程序实验室预约管理平台详细设计和实现

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

getid3 获取视频时长

1、首先&#xff0c;我们需要先下载一份PHP类—getid3https://codeload.github.com/JamesHeinrich/getID3/zip/master 2.我在laravel6.0 中使用 需要在composer.json 自动加载 否则系统访问不到 在命令行 执行 composer dump-autoload $getID3 new \getID3();//视频文件需要放…

【PostgreSql本地备份为dump文件与恢复】使用脚本一键备份为dump文件

环境&#xff1a;windows数据库&#xff1a;postgresql 1.准备脚本 backUpDb.bat 脚本为备份脚本&#xff0c;双击运行&#xff0c;右键可以选择编辑&#xff1b;restoreDb.bat 脚本为恢复脚本&#xff0c;双击运行&#xff0c;右键选择编辑&#xff1b; 1.1 脚本介绍 如上图…

数据结构:串(定义,基本操作,存储结构)

目录 1.串的定义2.串的基本操作3.字符集编码4.串的存储结构1.顺序存储2.链式存储 1.串的定义 串&#xff0c;即字符串( String&#xff09;是由零个或多个字符组成的有限序列。 一般记为s ‘a1a2……an’ (n ≥0) 其中&#xff0c;S是串名&#xff0c;单引号括起来的字符序列是…

企业清算有哪些类型?在哪里可以查看相关公告?

企业清算是什么&#xff1f; 企业清算指企业按章程规定解散以及由于破产或其他原因宣布终止经营后&#xff0c;对企业的财产、债权、债务进行全面清查&#xff0c;并进行收取债权&#xff0c;清偿债务和分配剩余财产的经济活动。 企业清算给分为破产清算&#xff0c;非破产清…

华为云交换数据空间 EDS:“可信、可控、可证”能力实现你的数据你做主

文章目录 前言一、数据安全流通价值的必要性和紧迫性1.1、交换数据空间&#xff08;EDS&#xff09;背景1.2、《数字中国建设整体布局规划》1.3、数据流通成为制约数据要素价值释放的瓶颈 二、华为云 EDS 解决方案介绍2.1、构建可控数据交换空间2.2、可控的数据交换框架2.3、定…

互联网医院|线上医疗引领行业发展

您是否曾经遇到过这样的问题&#xff1a;在忙碌的工作中&#xff0c;突然感到身体不适&#xff0c;但却又不想浪费时间和金钱去实体医院&#xff1f;或者是因为疫情的限制&#xff0c;出门看病变得困难重重&#xff1f;那么&#xff0c;今天我要向您介绍的&#xff0c;正是解决…

中断 NVIC的概念和原理

1.什么是中断 中断&#xff1a; 由于中断源的触发&#xff0c;常规程序被打断&#xff0c; CPU转 而运行中断响应函数&#xff0c;而后又回到常规程序的执行&#xff0c; 这一过程叫做中断。 中断优先级的概念 中断的意义和作用 中断处理的过程和术语 STM32 GPIO外部中断简…

【java:牛客每日三十题总结-3】

java:牛客每日三十题总结 总结如下 总结如下 集合相关知识点 Collection主要的子接口: List:可以存放重复内容 Set:不能存放重复内容,所有重复的内容靠hashCode()和equals()两个方法区分 Queue:队列接口 SortedSet:可以对集合中的数据进行排序 Map没有继承Collection接口&…

最新AI系统ChatGPT源码+AI绘画系统源码+支持GPT4.0+Midjourney绘画+搭建部署教程+附源码

一、AI创作系统 SparkAi创作系统是基于OpenAI很火的ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如…

黑豹程序员-SpringBoot中整合knife4j接口文档

1、Knife介绍 黑豹程序员-架构师学习路线图-百科&#xff1a;Knife4j API接口文档管理 2、坐标 <dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-spring-boot-starter</artifactId><version>2.0.7</version&…

银河麒麟等 Linux系统 安装 .net 3.1,net 6及更高版本的方法

确定 系统的版本。华为鲲鹏处理器是 Arm64位的。 于是到windows 官网下载对应版本 .net sdk 下载地址 https://dotnet.microsoft.com/zh-cn/download/dotnet 2.下载完成后&#xff0c;再linux 服务器 上进入到文件所在目录&#xff0c;建议全英文路径。 然后依次输入以下命令 …

图论09-桥和割点

文章目录 1 寻找桥的算法2 桥的代码实现3 寻找割点的算法4 割点的代码实现 1 寻找桥的算法 2 桥的代码实现 package Chapt06_Bridge;import java.util.ArrayList;public class FindBridges {private Graph G;private boolean[] visited;//ord数组记录访问的顺序private int or…

极狐GitLab CI 助力 .Net 项目研发效率和质量双提升

目录 .NET nuget 自动生成测试包&#xff08;prerelease&#xff09;版本号 .NET 版本号规范 持续集成自动打包 持续集成自动修改版本号 .NET 行级增量代码规范——拯救老项目 本地全量代码规范 行级增量代码规范 很多团队或开发者都会使用 C#、VB 等语言开发 .Net 应用…

区块链游戏,游戏开发

区块链游戏是一种基于区块链技术的新兴游戏类型&#xff0c;它具有去中心化、安全性高、透明度高、可追溯等特点。与传统的游戏开发相比&#xff0c;区块链游戏开发需要更多的技术和知识储备&#xff0c;同时也需要更加注重游戏本身的玩法和用户体验。 在区块链游戏中&#xff…

【PHP网页应用】MySQL数据库增删改查 基础版

使用PHP编写一个简单的网页&#xff0c;实现对MySQL数据库的增删改和展示操作 页面实现在index.php&#xff0c;其中basic.php为没有css美化的原始人版本 函数实现在database.php 目录 功能基本实现版 CSS美化版 basicindex.php index.php database.php 代码讲解 功能基…

红海云签约和兆服饰,科技引领服饰行业人力资源数字化转型

和兆服饰从事多品牌多品类经营管理&#xff0c;旗下拥有POLOSPORT、POLOKIDS、CARTELO等国际品牌。作为一个主打POLO文化的服饰品牌&#xff0c;诞生于美国的POLOSPORT拥有现代感的产品设计、系列化的产品搭配、全方位的服务&#xff0c;是最具美国马球精神的休闲时尚服饰品牌之…

【云栖2023】张治国:MaxCompute架构升级及开放性解读

简介&#xff1a; 本文根据2023云栖大会演讲实录整理而成&#xff0c;演讲信息如下 演讲人&#xff1a;张治国|阿里云智能计算平台研究员、阿里云MaxCompute负责人 演讲主题&#xff1a;MaxCompute架构升级及开放性解读 活动&#xff1a;2023云栖大会 MaxCompute发展经历了…

springcloud二手交易平台系统源码

开发技术&#xff1a; 大等于jdk1.8&#xff0c;大于mysql5.5&#xff0c;idea&#xff08;eclipse&#xff09;&#xff0c;nodejs&#xff0c;vscode&#xff08;webstorm&#xff09; springcloud springboot mybatis vue elementui mysql 功能介绍&#xff1a; 用户端&…