Java / Android 多线程和 synchroized 锁

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 thenit 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() {@Overridepublic Thread newThread(Runnable r) {return new Thread(r,"Thread-"+count.incrementAndGet());}};Runnable runnable = new Runnable() {@Overridepublic 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() {@Overridepublic 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>() {@Overridepublic 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;}@Overridepublic void runTest() {new Thread(new Runnable() {@Overridepublic 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); //intThreadFactory factory = new ThreadFactory() {@Overridepublic 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;}}@Overridepublic 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.mzph.cn/news/136976.shtml

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

相关文章

超全大厂UI库分享,可免费套用!

今天我们要给大家分享的是TDesign、Arco Design、Ant Design、Material design等6个优秀的大厂UI库&#xff0c;一次性打包送给大家&#xff0c;通通免费用。大厂UI库都是经过无数次的事件检验的&#xff0c;扛住了许多种使用场景和突发情况的组件资源库&#xff0c;是前人的经…

HarmonyOS NEXT 调优工具 Smart Perf Host 高效使用指南

在软件开发的过程中&#xff0c;很多开发者都经常会遇到一些性能问题&#xff0c;比如应用启动慢、点击滑动卡顿、应用后台被杀等&#xff0c;想要解决这些问题势必需要收集大量系统数据。而在收集数据的过程中&#xff0c;开发者则需要在各种工具和命令之间来回切换&#xff0…

k8s 部署mqtt —— 筑梦之路

mqtt是干嘛的&#xff0c;网上有很多资料&#xff0c;这里就不再赘述。 --- apiVersion: apps/v1 kind: Deployment metadata:labels:app: mqttname: mqttnamespace: default spec:replicas: 1selector:matchLabels:app: mqttstrategy:rollingUpdate:maxSurge: 25%maxUnavaila…

华为认证 | 11月底这门HCIP认证即将发布!

非常荣幸地通知您&#xff0c;华为认证HCIP-Storage V5.5&#xff08;中文版&#xff09;预计将于2023年11月30日正式对外发布。为了帮助您做好学习、培训和考试计划&#xff0c;现进行预发布通知&#xff0c;请您关注。 01 发布概述 基于“平台生态”战略&#xff0c;围绕“云…

Django快速入门(一)

Django三板斧 1. 基本使用 三板斧: HttpResponse,render,redirect from django.shortcuts import HttpResponse,render,redirect# 一. 返回字符串类型的数据 return HttpResponse(字符串) # 二. 返回HTML文件 # 1. 动态HTML页面: return render(request,login.html) def ab…

西门子S7-1200PLC混合通信编程(ModbusTcp和UDP通信)

S7-1200PLC的MODBUS-TCP通信 西门子PLC ModbusTcp通信访问网关后从站(SCL语言轮询状态机)-CSDN博客文章浏览阅读305次。西门子PLC的ModbusTcp通信在专栏已有很多文章介绍,所不同的是每个项目的通信需求都略有不同,今天我们以访问网关后的三个从站数据来举例,给出轮询的推荐…

iOS 16.4 之后真机与模拟器无法使用Safari调试H5页面问题

背景 iOS 16.4之后用真机调试H5时候发现&#xff0c;Safari中开发模块下面无法调试页面 解决方案 在WKWebView中设置以下代码解决 if (available(iOS 16.4, *)) {[_webView setInspectable:YES];}然后再次调试就可以了

[git] cherry pick 将某个分支的某次提交应用到当前分支

功能&#xff1a;将某个分支的某次提交应用到当前分支 应用场景&#xff1a; 在合并分支时&#xff0c;是将源分支的所有内容都合并到目标分支上&#xff0c;有的时候我们可能只需要合并源分支的某次或某几次的提交&#xff0c;这个时候我们就需要使用到git的cherry-pick操作…

边缘计算多角色智能计量插座:用电监测和资产管理的未来智能化引擎

目前主流的智能插座涵盖了红外遥控&#xff08;控制空调和电视等带有红外标准的电器&#xff09;&#xff0c;配备着测温、测湿等仓库应用场景&#xff0c;配备了人体红外或者毫米波雷达作为联动控制&#xff0c;但是大家有没有思考一个问题&#xff0c;就是随着对接的深入&…

易点易动固定资产管理系统:实现全生命周期闭环式管理和快速盘点

固定资产管理对于企业来说至关重要&#xff0c;它涉及到资产的采购、领用、使用、维护和报废等各个环节。然而&#xff0c;传统的固定资产管理方式往往繁琐、耗时&#xff0c;容易导致信息不准确和资源浪费。为了解决这些问题&#xff0c;我们引入易点易动固定资产管理系统&…

DevOps简介

DevOps简介 1、DevOps的起源2、什么是DevOps3、DevOps的发展现状4、DevOps与虚拟化、容器 1、DevOps的起源 上个世纪40年代&#xff0c;世界上第一台计算机诞生。计算机离不开程序&#xff08;Program&#xff09;驱动&#xff0c;而负责编写程序的人&#xff0c;被称为程序员&…

Kotlin基础数据类型和运算符

原文链接 Kotlin Types and Operators Kotlin是新一代的基于JVM的静态多范式编程语言&#xff0c;功能强大&#xff0c;语法简洁&#xff0c;前面已经做过Kotlin的基本的介绍&#xff0c;今天就来深入的学习一下它的数据类型和运算操作符。 数据类型 与大部分语言不同的是&am…

socket编程中的EINTR是什么?

socket编程中的EINTR是什么? 在socket编程中&#xff0c;我们时常在accept/read/write等接口调用的异常处理的部分看到对于EINTR的处理&#xff0c;例如下面这样的语句&#xff1a; repeat: if(read(fd, buff, size) < 0) {if(errno EINTR)goto repeat;elseprintf("…

三菱FX3U系列-定位指令

目录 一、简介 二、指令形式 1、相对定位[DRVI、DDRVI] 2、绝对定位[DRVA、DDRVA] 三、总结 一、简介 定位指令用于控制伺服电机或步进电机的位置移动。可以通过改变脉冲频率和脉冲数量来控制电机的移动速度和移动距离&#xff0c;同时还可以指定移动的方向。 二、指令形…

Linux下的环境变量【详解】

Linux下的环境变量 一&#xff0c;环境变量的概念1 概述2 环境变量的分类3 常见的环境变量4 查看环境变量4.1 shell变量4.2 查看环境变量 5 添加和删除环境变量5.1 添加环境变量5.2 删除环境变量 6. 通过代码如何获取环境变量6.1 命令行的第三个参数6.2 通过第三方变量environ获…

Linux 的热插拔机制通过 Udev(用户空间设备)实现、守护进程

一、Udev作用概述 udev机制简介udev工作流程图 二、Linux的热拔插UDEV机制 三、守护进程 守护进程概念守护进程在后台运行基本特点 四、守护进程和后台进程的区别 一、Udev作用概述 udev机制简介 Udev&#xff08;用户空间设备&#xff09;是一个 Linux 系统中用于动态管…

微信号绑定50个开发者小程序以后超额如何删除不用的

我们在开发微信小程序的时候&#xff0c;当前开发者工具登录的必须是该小程序的开发者才能进行小程序的开发&#xff0c;添加开发者的步骤是&#xff1a; 添加开发者 1、进入微信开放平台&#xff0c;然后扫码进入管理平台 2、找到下图所示位置 3:、输入要添加的微信账号&am…

LCD英文字模库(16x8)模拟测试程序

字模 字模&#xff0c;就是把文字符号转换为LCD能识别的像素点阵信息。 电子发烧友可能都熟悉字模的用途。就是调用者通过向LCD模块发送字模数据&#xff0c;LCD根据字模数据在LCD面板上相应的像素描绘出图形或文字。 现在&#xff0c;大部分的LCD都内置了字模库&#xff0c…

11-09 周四 CNN 卷积神经网络基础知识

11-09 周四 CNN 卷积神经网络 时间版本修改人描述2023年11月9日09:38:12V0.1宋全恒新建文档 简介 学习一下CNN&#xff0c;卷积神经网络。使用的视频课程。视觉相关的任务&#xff1a; 人脸识别 卷积网络与传统网络的区别&#xff1a; <img altimage-20231109094400591 s…

电脑怎么录制视频,录制的视频怎么剪辑?

在现今数字化的时代&#xff0c;视频成为了人们日常生活中不可或缺的一部分。因此&#xff0c;对于一些需要制作视频教程、录制游戏或者是进行视频演示的人来说&#xff0c;电脑录屏已经成为了一个必不可少的工具。那么&#xff0c;对于这些人来说&#xff0c;如何选择一个好用…