当前位置: 首页 > news >正文

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.lryc.cn/news/224898.html

相关文章:

  • 基于51单片机的万年历-脉搏计仿真及源程序
  • 【ARFoundation学习笔记】点云与参考点
  • uni-app:js实现数组中的相关处理-数组复制
  • 8 STM32标准库函数 之 实时时钟(RTC)所有函数的介绍及使用
  • ARMday04(开发版简介、LED点灯)
  • 国际腾讯云:云服务器疑似被病毒入侵问题解决方案!!!
  • Perl语言用多线程爬取商品信息并做可视化处理
  • 认识计算机-JavaEE初阶
  • you-get - 使用代码下载视频
  • 【Proteus仿真】【51单片机】汽车尾灯控制设计
  • 浙大恩特客户资源管理系统任意文件上传漏洞复现
  • 史上第一款AOSP开发的IDE (支持Java/Kotlin/C++/Jni/Native/Shell/Python)
  • GCC + Vscode 搭建 nRF52xxx 开发环境
  • Linux应用开发基础知识——Framebuffer 应用编程(四)
  • 智安网络|数据库入门秘籍:通俗易懂,轻松掌握与实践
  • EXCEL中安装多个vsto插件,插件之间互相影响功能,怎么解决
  • Java枚举
  • 基于MATLAB的关节型六轴机械臂轨迹规划仿真
  • 双11狂欢最后一天
  • YOLOX: Exceeding YOLO Series in 2021(2021.8)
  • HBuilderX 运行Android App项目至雷电模拟器
  • Java进阶(JVM调优)——阿里云的Arthas的使用 安装和使用 死锁查找案例,重新加载案例,慢调用分析
  • 续:将基于Nasm汇编的打字小游戏,移植到DOSBox
  • 外部访问K8S集群内部的kafka集群服务
  • AttributeError: module ‘tensorflow‘ has no attribute ‘contrib‘解决办法
  • 物奇平台耳机恢复出厂设置功能实现
  • RFID携手制造业升级,为锂电池生产带来前所未有的可靠性
  • 【星海出品】flask (四) 三方工具使用
  • MongoDB 索引
  • [Hive] INSERT OVERWRITE DIRECTORY要注意的问题