在线程里使用线程外的变量为什么一定要是final类型
public class CyclicBarrierDemo {
public static void main(String[] args) {
/*
* 七龙珠
* */
CyclicBarrier cyclicBarrier = new CyclicBarrier(7,()->{
System.out.println("召唤神龙");
});
for (int i = 0; i < 7; i++) {
int finalI = i;
new Thread(()->{
System.out.println(finalI);
},String.valueOf(i+1)).start();
final int temp=i;
new Thread(()->{
System.out.println(temp);
},String.valueOf(i+1)).start();
}
}
}
从上面代码不难看出,直接在线程里面使用外部的变量是会提示报错的!
idea提供的解决的办法是用一个临时变量来存储
为什么要临时变量来存储值呢?
当存在大量线程的情况下,启动线程的时间很短,启动了不代表线程执行完结束了,因此线程本身生命周期还没有结束,而for循环定义的临时变量生命周期可能已经结束了,当线程里面使用这个变量的时候再来访问就会出错
从例子可以看出,for循环里面直接用临时变量存储就行了,拿为什么还要加final来修饰呢?
final定义的变量不能更改,在定义的时候就已经确定了值,单核cpu可能不存在这个问题,但是多核cpu并行处理这个线程的时候就可能会导致两个线程访问的是同一个变量,但是第一个线程本该访问这个变量的值为1,由于某些原因中间延迟执行了,当要访问这个变量的时候,已经被另外一个线程修改了这个变量的值,导致结果差强人意
在线程里使用线程外的变量为什么一定要是final类型的更多相关文章
- 【JAVA】在线程里使用线程外的变量为什么一定要是final类型
这个情况真的碰到很多,开始的时候也很难理解,但是既然IDE提示要final那我就final咯,跑通就行管那么多呢.然而这并不是科学的学习方法,万一面试问你呢那不是倒了大霉. OK,看了一些
- 匿名内部类不能访问外部类方法中的局部变量,除非变量被声明为final类型
1. 这里所说的"匿名内部类"主要是指在其外部类的成员方法内定义,同时完成实例化的类,若其访问该成员方法中的局部变量,局部变量必须要被final修饰.2. 原因是编译程序实现上的困 ...
- 20181106_线程之异常_取消_变量_安全Lock
一. 线程的异常处理: try { TaskFactory taskFactory = new TaskFactory(); List<Task> taskList = new List& ...
- 小谈Java里的线程
今天,我们来谈一谈Java里的线程. 一.进程与线程的基本概念 大家可能没听过线程这个概念,但是相信,用计算机的朋友都听过进程这个概念.打开电脑的任务管理器,我们就可以看到许多进程.它们主要分为三类, ...
- Winform软件,不要在线程里操作UI
对于Winform软件,不要在线程里操作UI,不要相信:StartForm.CheckForIllegalCrossThreadCalls = false; 于是,把所有的代码都改成主线程委托调用的方 ...
- 简短总结一下C#里跨线程更新UI(转)
摘自: http://my.oschina.net/sdqxcxh/blog/53707 跨线程更新UI是写多线程程序尤其是通信类的程序经常遇到的问题,这里面主要的问题是冲突,比如数据线程想要更新UI ...
- 简短总结一下C#里跨线程更新UI
摘自: http://my.oschina.net/sdqxcxh/blog/53707 跨线程更新UI是写多线程程序尤其是通信类的程序经常遇到的问题,这里面主要的问题是冲突,比如数据线程想要更新UI ...
- Qt 的线程与事件循环——可打印threadid进行观察槽函数到底是在哪个线程里执行,学习moveToThread的使用)
周末天冷,索性把电脑抱到床上上网,这几天看了 dbzhang800 博客关于 Qt 事件循环的几篇 Blog,发现自己对 Qt 的事件循环有不少误解.从来只看到现象,这次借 dbzhang800 的博 ...
- Qt线程QThread简析(8个线程等级,在UI线程里可调用thread->wait()等待线程结束,exit()可直接退出线程,setStackSize设置线程堆栈,首次见到Qt::HANDLE,QThreadData和QThreadPrivate)
QThread实例代表一个线程,我们可以重新实现QThread::run(),要新建一个线程,我们应该先继承QThread并重新实现run()函数. 需要注意的是: 1.必须在创建QThread对象之 ...
- Java并发(五)线程池使用番外-分析RejectedExecutionException异常
目录 一.入门示例 二.异常场景1 三.异常场景2 四.解决方法 之前在使用线程池的时候,出现了 java.util.concurrent.RejectedExecutionException ,原因 ...
随机推荐
- 2流高手速成记(之五):Springboot整合Shiro实现安全管理
废话不多说,咱们直接接上回 上一篇我们讲了如何使用Springboot框架整合Nosql,并于文章最后部分引入了服务端Session的概念 而早在上上一篇中,我们则已经讲到了如何使用Springboo ...
- JavaWeb3
1. 会话技术 会话:一次会话中包含多次请求和响应 一次会话:浏览器第一次给服务器资源发送请求,会话建立,直到有一方断开为止 功能:在一次会话的范围内的多次请求间共享数据 方式: 客户端会话技术:Co ...
- mindxdl--common--log_record.go
// Copyright (c) 2021. Huawei Technologies Co., Ltd. All rights reserved.// Package common define co ...
- 【云原生 · Kubernetes】Jenkins+Gitlab+Rancher+Docker 实现自动构建镜像的 CI 平台(一)
1 准备 Jenkins+Gitlab 实验环境 1.1 准备实验环境:恢复到以一下快照:该环境已经配置好 jenkins+gitlab+sonar-配置通 主机角色: IP 地址 运行的服务 硬件配 ...
- 如何使用zx编写shell脚本
前言 在这篇文章中,我们将学习谷歌的zx库提供了什么,以及我们如何使用它来用Node.js编写shell脚本.然后,我们将学习如何通过构建一个命令行工具来使用zx的功能,帮助我们为新的Node.js项 ...
- 1. scrapy 框架应该怎么学习(前言)
其实 scrapy 框架并不难学习, 我觉得分为两部分: 命令 和 代码逻辑的构建 1. 如何学习命令 其实 scrapy 已经帮我们做好了很充足的说明了, 下面我来说如何好好利用这些说明 scrap ...
- easui datagrid 行获取后台sql所有数据:支持行chockbox多选,输出选中行任意属性;支持点击表中属性实现跳转;支持分页。
easyUI datagrid 代码: <table id="tabgrid20170726191838251403" class="easyui-datagrid ...
- 【Java EE】Day01 基础加强、Junit单元测试、反射、注解
〇.总结 1.测试:三个注解.断言判断 2.反射:三个阶段获取字节码对象的三种方式.忽略成员变量权限方法setAccessible(true) 3.注解:内置注解SupressWarning& ...
- .NET 6 中外部引用项目NU1105异常问题解决
.NET 6 Project中,添加了其他解决方案的工程后,本地能编译通过,代码签入后,其他同事下载代码,编译报错: 错误 NU1105 找不到"E:\Teld\01Code\TTP_CTP ...
- MongoDB - 数据模型的设计模式
简介 官方文章的地址是 Building with Patterns: A Summary,其中汇总了 12 种设计模式及使用场景. 上述的图表列举了 12 种设计模式及应用场景,主要是以下这些: 近 ...