摘要:一个线程做完,并将数据刷新回主内存了,下一个线程才会启动。声明了的变量在被赋值之后,线程会立刻将值写回主内存在读取变量时,线程会到主内存去读取变量的最新值。
一个例子:
public class Counter { public static int count = 0; public synchronized static void inc() { count++; } public static void main(String[] args) { for (int i = 0; i < 100; i++) { new Thread(new Runnable() { @Override public void run() { Counter.inc(); } }).start(); } while(Thread.activeCount() > 1){ Thread.yield(); } System.out.println("运行结果:Counter.count=" + Counter.count); } }
使用线程:
1.新建自定义类,继承接口Runnable,并实现方法run()。
2.实例化,作为参数传给thread(),调用thread的start方法,运行线程。该线程就会运行run()的代码。
本来,main方法执行过程便是一个线程,就好比一个人A在干活。新建一个线程,就好比又召集了一个人来同时干活。上面的例子中,这新来的人——新建的线程——将会和A一起同时地干活。
所以,如果不在main线程里判断其他100个线程是否允许完毕的话,A(main函数所在线程)可能将会比其他人有些人干的更快,那么——main函数的线程先于其他线程跑完,导致打印的结果不是最终100个线程跑完的结果。
synchronized关键字声明了该方法为同步方法。意即,同时只允许一个线程运行这个方法。前面我们说过,新建并启动了100个线程,这100个人都准备开始干活,但是带有synchronized关键字的方法只允许同时一个人使用。也就是说这100个人需要排队等待,先来后到。
为什么要同步,先来后到呢?
这里就存在内存使用的问题。
每一个线程在使用实例变量的时候,会复制一份副本到自己的栈内存中(每个线程独自享有)。倘若实例变量为5,现有两个线程同时复制了5到自己的线程内存。他们各自做加1操作,随后线程A将结果6,写回到主内存中;随后线程B也将6写回到主内存中。
但是我们的初衷可能是需要该变量作为计数器,反映所做操作的次数,但是这里两个线程共做了2次操作,变量的值却只加了1。
这个时候,使用synchronized,方法就会“同步”。一个线程做完,并将数据刷新回主内存了,下一个线程才会启动。
就好比,房子里有一个房间,想进入的人必须拿到门口的桌子上放着的一把钥匙,没有钥匙的人只可在门外等候。只有等这个人做完所有工作,并且把钥匙还回门口的桌子,下一个人才能从桌子拿到钥匙,进入房间。
volatile
Java还提供了关键字volatile。声明了volatile的变量在被赋值之后,线程会立刻将值写回主内存;在读取变量时,线程会到主内存去读取变量的最新值。说白了,它增加了线程与主内存的通信,以期望解决多线程写数据的同步问题。
但这也并不一定能保证上述计数器的问题。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/66407.html
摘要:哪吒社区技能树打卡打卡贴函数式接口简介领域优质创作者哪吒公众号作者架构师奋斗者扫描主页左侧二维码,加入群聊,一起学习一起进步欢迎点赞收藏留言前情提要无意间听到领导们的谈话,现在公司的现状是码农太多,但能独立带队的人太少,简而言之,不缺干 ? 哪吒社区Java技能树打卡 【打卡贴 day2...
摘要:最近听很多面试的小伙伴说,网上往往是一篇一篇的多线程的文章,除了书籍没有什么学习多线程的一系列文章。将此线程标记为线程或用户线程。 最近听很多面试的小伙伴说,网上往往是一篇一篇的Java多线程的文章,除了书籍没有什么学习多线程的一系列文章。但是仅仅凭借一两篇文章很难对多线程有系统的学习,而且面试的时候多线程这方面的知识往往也是考察的重点,所以考虑之下决定写一系列关于Java多线程的文章...
摘要:我的学习笔记汇总标签笔记分为两大部分和笔记内容主要是对一些基础特性和编程细节进行总结整理,适合了解基础语法,想进一步深入学习的人如果觉得不错,请给,这也是对我的鼓励,有什么意见欢迎留言反馈目录基础巩固笔记反射基础巩固笔记泛型基础巩 我的java&javaweb学习笔记(汇总) 标签: java [TOC] 笔记分为两大部分:javase和javaweb javase javawe...
摘要:包含了支持服务开发的类,并为提供基础,如语言基础操作操作网络通信以及多线程等技术。在运行文件时,的解释器对这些字节码进行解释执行,执行过程中需要加入的类在连接阶段被载入到运行环境中。支持多个线程同时执行,并提供多线程之间的同步机制。 1.什么是Java语言 简单地说,Java 是由 Sun Microsystems 公司于 1995 年推出的一门面向对象程序设计语言。2009 年 Or...
阅读 1628·2021-09-28 09:35
阅读 1044·2019-08-30 15:54
阅读 1636·2019-08-30 15:44
阅读 3349·2019-08-30 14:09
阅读 470·2019-08-29 14:05
阅读 2644·2019-08-28 17:53
阅读 1965·2019-08-26 13:41
阅读 1678·2019-08-26 13:26