今天趁空闲时间看了点线程方面的知识

首先看的是volatile关键字,按照我之前书上看到的一点知识,自己的理解是,volatile关键字会阻止编译优化,因为cpu每次读取数据是并不是从高速缓存中读取,而是取内存中的数据。这是自己的一点简单的理解,可能有错误。我之前只是看了点线程方面的知识,只是在自己写代码的时候很少(根本没用到),就是自己学习的时候跟着书上敲了代码。

实习的时候要我写个压力测试,1000个线程同时发请求,统计请求失败的次数,我用了volatile关键字,但是感觉有点问题,今天就测试了下。

我之前一直认为,用volatile关键字强调的变量在 多线程的自增是不会出现问题的

下面是我的第一次测试代码

import java.util.ArrayList;
import java.util.List; public class Count { private static volatile int count = 0; public static void inc() {
count++;
} public static int getCount() {
return count;
} public static void main(String[] args) throws Exception {
List<Thread> list = new ArrayList<Thread>(100);
for (int i = 0; i < 100; i++) {
list.add(new Thread(new Runnable() {
@Override
public void run() {
// for(int i=0;i<100;i++){
Count.inc();
// }
}
}));
} for (Thread t : list) {
t.start();
} for (Thread t : list) {
t.join();
} System.out.println("-----end-----");
System.out.println(Count.getCount()); } }

我测试了很多次,最后的结果确实是100,让我差点都以为上面的结论是正确的

但是我从一本书上看到。在run方法里面再套个循环,就是把上面的注释取消掉会出现问题

现在才进行测试,结果确实出现问题了,预期结果是10000,但是测试结果总是9800+,9900+,就是到不了10000.

但是有注释和没注释,这段代码有区别吗?我想了半天这段代码的区别,觉得可能是每个线程运行的时间太短了,导致出现了预期的结果

继续测试,还是加上注释,将100次循环改为1000次,测试结果为999。

这下终于推翻了  用volatile关键字强调的变量在 多线程的自增是不会出现问题的  这个结论。

但是得到这个结论的同时,我不知道volatile这个关键字到底应该用在哪里了~~

这真是个纠结的问题,回去查下资料,各位大神也可以帮下忙

java 线程基础学习的更多相关文章

  1. Java线程池学习

    Java线程池学习 Executor框架简介 在Java 5之后,并发编程引入了一堆新的启动.调度和管理线程的API.Executor框架便是Java 5中引入的,其内部使用了线程池机制,它在java ...

  2. Java【基础学习】之暴力求素数【用数组返回】

    Java[基础学习]之暴力求素数[用数组返回] */ import java.util.*; public class Main{ public static void main(String[] a ...

  3. Java 线程基础

    Java 线程基础

  4. Java基础学习总结(94)——Java线程再学习

    Java线程有哪些不太为人所知的技巧与用法? 萝卜白菜各有所爱.像我就喜欢Java.学无止境,这也是我喜欢它的一个原因.日常工作中你所用到的工具,通常都有些你从来没有了解过的东西,比方说某个方法或者是 ...

  5. Java线程机制学习

    前面的文章中总结过Java中用来解决共享资源竞争导致线程不安全的几种常用方式: synchronized: ReentrantLock: ThreadLocal: 这些都是在简单介绍了基本用法的基础上 ...

  6. java线程基础知识----线程与锁

    我们上一章已经谈到java线程的基础知识,我们学习了Thread的基础知识,今天我们开始学习java线程和锁. 1. 首先我们应该了解一下Object类的一些性质以其方法,首先我们知道Object类的 ...

  7. java线程基础知识----线程基础知识

    不知道从什么时候开始,学习知识变成了一个短期记忆的过程,总是容易忘记自己当初学懂的知识(fuck!),不知道是自己没有经常使用还是当初理解的不够深入.今天准备再对java的线程进行一下系统的学习,希望 ...

  8. java线程基础巩固---线程生命周期以及start方法源码剖析

    上篇中介绍了如何启动一个线程,通过调用start()方法才能创建并使用新线程,并且这个start()是非阻塞的,调用之后立马就返回的,实际上它是线程生命周期环节中的一种,所以这里阐述一下线程的一个完整 ...

  9. Java 线程基础知识

    前言 什么是线程?线程,有时被称为轻量进程(Lightweight Process,LWP),是程序执行流的最小单元.一个标准的线程由线程 ID,当前指令指针 (PC),寄存器集合和堆栈组成.另外,线 ...

随机推荐

  1. python网络编程——网络IO模型

    1 网络IO模型介绍 服务器端编程经常需要构造高性能的IO模型,常见的IO模型有四种:    (1)同步阻塞IO(Blocking IO):即传统的IO模型.    (2)同步非阻塞IO(Non-bl ...

  2. make cmake catkin_make

    在Linux下进行C语言编程,必然要采用GNU GCC来编译C源代码生成可执行程序. 一.GCC快速入门 Gcc指令的一般格式为:Gcc [选项] 要编译的文件 [选项] [目标文件] 其中,目标文件 ...

  3. String创建方式的区别

    String str0 = "abc"; String str1 = new String("abc"); 第一句执行后,会在String pool中创建一个& ...

  4. 在Linux下创建分区和文件系统的方法详解

    在 Linux 中创建分区或新的文件系统通常意味着一件事:安装 Gnome Parted 分区编辑器(GParted).对于大多数 Linux 用户而言,这是唯一的办法.不过,你是否考虑过在终端创建这 ...

  5. gcm 被微信弃用的原因

    作者:feng xixi链接:https://www.zhihu.com/question/21514839/answer/18496706来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商 ...

  6. 2017 湘潭邀请赛&JSCPC G&J

    训练的时候对G想了一个假算法..也有很大可能是写错了.. 下来一看别人的G 看起来很奇妙.. 开始把所有的左括号翻成右括号,然后cost*=-1 这样在优先队列中就是最优的 然后for每一段 如果前缀 ...

  7. DateTime和DateTimeOffset的区别

    1,DateTime 表示时间上的一刻,通常以日期和当天时间来表示. 2, DateTimeOffset 表示一个时间点,通常以相对于协调世界时(UTC)的日期和时间来表示. 3,下面是微软官方给出的 ...

  8. matplotlib之散点图

    环境:windows系统,anaconda3 64位,python 3.6 1.初认识 基本代码如下: import numpy as np import matplotlib.pyplot as p ...

  9. JNI_Z_10_Java的数组

    在Java中数组分为两种: (1).基本类型数组 (2).对象类型(Object[])的数组 (数组中存放的是指向Java对象中的引用) 一个能通用于两种不同类型数组的函数: GetArrayLeng ...

  10. Eclipse工具栏上android的机器人小图标不见了

    可以通过「Window」⇒「Customize Perspective」⇒「Tool Bar Visibility」Tab画面上选择Android SDK and AVD Manager来显示