java 线程基础学习

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

首先看的是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这个关键字到底应该用在哪里了~~

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

时间: 2024-10-29 10:47:42

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

Java 线程池学习

Reference: <创建Java线程池>[1],<Java线程:新特征-线程池>[2], <Java线程池学习>[3],<线程池ThreadPoolExecutor使用简介>[4],<Java5中的线程池实例讲解>[5],<ThreadPoolExecutor使用和思考>[6] [1]中博主自己通过ThreadGroup实现一个线程池(挺方便理解的),使用的是jdk1.4版本,Jdk1.5版本以上提供了现成的线程池. [2]中介绍

Java 线程基础

目录 Java 线程基础  一.线程简介  二.线程基本用法  三.线程间通信  四.线程状态  参考资料 Java 线程基础 ?? 本文以及示例源码已归档在 javacore 一.线程简介 什么是进程 什么是线程 进程和线程的区别 二.线程基本用法 创建线程 线程休眠 线程礼让 终止线程 守护线程 FAQ 三.线程间通信 wait/notify/notifyAll join 管道 四.线程状态 参考资料 一.线程简介 什么是进程 简言之,进程可视为一个正在运行的程序.它是系统运行程序的基本单位

并发编程总结——java线程基础1

最近没事,顺便看看java并发编程的东西,然后总结纪录下来,大家如果能看到帮忙指正指正哈哈,另外一方面也为以后自己回顾的时候可以看看. 关于并发编程,准备从几个点切入: 1.java线程几本知识 2.juc原子类 3.锁 4.juc集合 5.线程池 ------------------------------------------------------------------- 分割线开始.... 说到多线程,java中超父类Object中有wait()和notify()方法,包括Runna

Java线程基础知识(状态、共享与协作)

1.基础概念 CPU核心数和线程数的关系 核心数:线程数=1:1 ;使用了超线程技术后---> 1:2 CPU时间片轮转机制 又称RR调度,会导致上下文切换 什么是进程和线程 进程:程序运行资源分配的最小单位,进程内部有多个线程,会共享这个进程的资源 线程:CPU调度的最小单位,必须依赖进程而存在. 澄清并行和并发 并行:同一时刻,可以同时处理事情的能力 并发:与单位时间相关,在单位时间内可以处理事情的能力 高并发编程的意义.好处和注意事项 好处:充分利用cpu的资源.加快用户响应的时间,程序模

java线程基础梳理

java线程 概述 进程:运行时概念,运行的应用程序,进程间不能共享内存 线程:应用程序内并发执行的代码段,可以共享堆内存和方法区内存,而栈内存是独立的. 并发理解:在单核机器上,从微观角度来看,一段时间内cup只能执行一个任务,但是因为cup在只执行一段代码段的时候大部分的时间是处于等待程序的,所以可以再开几条程序,然后通过轮询机制,让cpu执行多个进程,从宏观角度来看就是所谓的并发.如果机器是多核,那么就是真正的并发. 线程调度模型 线程的调度模型分为: 分时调度模型和抢占式调度模型,Jav

Java线程池学习

一.实现Java多线程的方法 1.继承Thread类创建多线程 Thread类本质实现了Runnable接口.启动线程为start0()方法.是个native方法. 1 public class ThreadProcess extends Thread { 2 3 @Override 4 public void run(){ 5 long lastTime = System.currentTimeMillis(); 6 for(int i = 0; i < 1; i++){ 7 int ele

Java线程浅学习

 线程概述 线程是程序运行的基本执行单位,当操作系统执行一个程序时,会创建一个进程,而这个进程至少创建一个线程(主线程)作为这个程序的入口点.所以,在操作系统中运行的程序都至少有一个主线程. 进程和线程是现代操作系统必不可少的运行模型,在操作系统中可以有多个进程,这些进程包括系统进程(系统内部创建的进程)和用户进程(用户程序创建的进程),一个进程可以有多个线程.进程之间不存在内存共享,就是说,系统中的进程都是在各自的内存空间中运行的.但是一个进程中的线程可以共享系统分配给这个进程的内存空间.

java的基础学习(1)

在暑假荒废一星期,武汉看海之后.为了面对接下来的广州实习,我又重新温习了java的一些基本特征和进行手打代码.因为之前的学习更多是停留在纸面的理解上,没有实际的代码编辑.这两天学习要点在于对java的继承,重载,方法覆盖,多态以及约瑟夫问题. 重载,具有相同的方法名,但在参数的个数,类型,顺序上至少要有一个不同.返回类型和修饰符可以不同,但如果仅仅是返回类型不同,或仅仅是修饰符不同,是不足以构成方法的重载的. 方法的覆盖,是在父类已有成员方法的基础上,子类可以有对同名成员方法的不同实现,将会使父

【Java】基础学习0-为什么学习Java?

背景 众所周知,Java的开发人员数量远远要多于Python的开发人员.作为企业的软件开发来讲,一般公司都选择Java作为第一个开发语言.市场上很多的管理系统,特别是B/S架构的网站,数据查询相关产品,基本上都是Java开发的. 博主有一定的Python基础,但是在最近的工作过程中越来越感觉到多掌握一门编程语言的重要性.现在很多公司的招聘信息中明确表示,测试必须要熟悉Android/iOS中的一种,iOS开发需要iOS环境,安卓开发也要Java基础.那么你就比只会Python编写测试脚本的其他测