关于java数组并发与缓存行的一些疑惑,求解惑 缓存并发java 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 public class MessagePool { Message[] buffer; Sequence sequence = new Sequence(); public MessagePool(int size){ buffer = new Message[size]; } public void put(Message msg){ long index = sequence.incrementAndGet(); buffer[(int) index] = msg; } public Message[] getBuffer(){ return buffer; }}这样的代码是我针对第一个疑问自己写的测试,sequence原子自增计数器。我测试了100000个协程,1s完成。100000个线程10S完成。但是我不知道这样对不对?真心求指导。 想要在Java平台实现通用的padding是很困难的,因为数组是对象,对象里就有其他内部的数据,在jvm版本一上避免了false sharing,在版本2中就未必有效了。另外,至于是不是线程安全的,要看有没有读写操作,如果只有写操作,安全不安全又有什么关系,如果只有读操作,也不会出现不安全如果上述数组有读写操作,且缺乏同步,数组元素的可见性是无法保证的。至于更新数据到内存,JSR133规范第11节中有规定,即使没有同步,也不能出现word tearing(字分裂)情形。 按照规范来说,理论上应该不影响,具体与虚拟机的实现和自己的计算机能不能处理单字节有关,是不?另外下面的例子import java.util.Arrays;public class WordTearing extends Thread { static final int LENGTH = 80; static final int ITERS = 1000000; static byte[] counts = new byte[LENGTH]; static Thread[] threads = new Thread[LENGTH]; final int id; WordTearing(int i) { id = i; } public void run() { byte v = 0; for (int i = 0; i < ITERS; i++) { byte v2 = counts[id]; if (v != v2) { System.err.println("Word-Tearing found: " + "counts[" + id + "] = " + v2 + ", should be " + v); return; } v++; counts[id] = v; } } public static void main(String[] args) { for (int i = 0; i < LENGTH; ++i) (threads[i] = new WordTearing(i)).start(); System.out.println(Arrays.toString(counts)); System.out.println(Integer.toBinaryString(ITERS)); }}我打印出counts数组的内容,理论上应该都是64 ,然而最后的结果如下[64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 113, -127]首先,我的计算机应该没有字分裂的问题,最后的113,,127的结果就让我很奇怪了。另外,我又自编自演了一出package graph.lab;import java.util.Arrays;public class WordTearingTest { public static void main(String[] args){ int[] m = new int[100]; ArrayUpdater[] aus = new ArrayUpdater[100]; for(int i=0;i<100;i++){ aus[i] = new ArrayUpdater(i, m); } for(int i=0;i<100;i++){ aus[i].start(); } System.out.println(Arrays.toString(m)); }}class ArrayUpdater extends Thread{ int[] m ; int id ; public ArrayUpdater(int id ,int [] m){ this.id = id; this.m = m; } public void run(){ m[id] = id; }}结果如下:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 0]虽然有很大一部分可能会出现正确的结果,但是也会出现不正确的结果,例如上面这个结果,最后的0。被搞的头大了~~大牛,求指导。 #5两段程序都没保证thread已经执行完毕排序打印,大大的不妥数据不对应该是因为线程内run()未执行完 即使是static的变量,再进入Thread时依然只是copy一个副本,出去Thread的时候再回写到static变量,so,出现这种情况很正常 是的,我加了 sleep(1000) 后结果就正确了 如何保留上次设置的字体,背景颜色 如何卸载jre 菜鸟问题:希望有人回答 Java混淆器的混淆原理 请高手说说面向对象的几个概念,谢谢了! 面试题,求高手支招...急 请教高手帮我把这段代码转成JAVA程序,本人急用,谢谢! 请教高手如何有效阅读开源项目源代码? 抛出和捕获 用jbuilder6。0和mobileset2。0 开发手机程序! 求一身份证正则表达式 java如何监控磁盘IO性能
Sequence sequence = new Sequence();
public MessagePool(int size){
buffer = new Message[size];
}
public void put(Message msg){
long index = sequence.incrementAndGet();
buffer[(int) index] = msg;
}
public Message[] getBuffer(){
return buffer;
}
}这样的代码是我针对第一个疑问自己写的测试,sequence原子自增计数器。我测试了100000个协程,1s完成。100000个线程10S完成。但是我不知道这样对不对?真心求指导。
static final int LENGTH = 80;
static final int ITERS = 1000000;
static byte[] counts = new byte[LENGTH];
static Thread[] threads = new Thread[LENGTH];
final int id; WordTearing(int i) {
id = i;
} public void run() {
byte v = 0;
for (int i = 0; i < ITERS; i++) {
byte v2 = counts[id];
if (v != v2) {
System.err.println("Word-Tearing found: " + "counts[" + id
+ "] = " + v2 + ", should be " + v);
return;
}
v++;
counts[id] = v;
}
} public static void main(String[] args) {
for (int i = 0; i < LENGTH; ++i)
(threads[i] = new WordTearing(i)).start();
System.out.println(Arrays.toString(counts));
System.out.println(Integer.toBinaryString(ITERS));
}
}
我打印出counts数组的内容,理论上应该都是64 ,然而最后的结果如下
[64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 113, -127]
首先,我的计算机应该没有字分裂的问题,最后的113,,127的结果就让我很奇怪了。另外,我又自编自演了一出package graph.lab;import java.util.Arrays;public class WordTearingTest { public static void main(String[] args){
int[] m = new int[100];
ArrayUpdater[] aus = new ArrayUpdater[100];
for(int i=0;i<100;i++){
aus[i] = new ArrayUpdater(i, m);
}
for(int i=0;i<100;i++){
aus[i].start();
}
System.out.println(Arrays.toString(m));
}
}class ArrayUpdater extends Thread{
int[] m ;
int id ;
public ArrayUpdater(int id ,int [] m){
this.id = id;
this.m = m;
}
public void run(){
m[id] = id;
}
}结果如下:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 0]虽然有很大一部分可能会出现正确的结果,但是也会出现不正确的结果,例如上面这个结果,最后的0。被搞的头大了~~大牛,求指导。
数据不对应该是因为线程内run()未执行完
是的,我加了 sleep(1000) 后结果就正确了