小编Mar*_*tin的帖子

指令重新排序和发生在java之前的关系

在Java Concurrency In Practice一书中,我们被告知可以通过编译器,JVM在运行时甚至由处理器重新排序程序的指令.因此,我们应该假设执行的程序不会以与我们在源代码中指定的顺序完全相同的顺序执行其指令.

但是,讨论Java内存模型的最后一章提供了一个先前发生的规则列表,指出了JVM保留了哪些指令排序.这些规则中的第一条是:

  • "程序顺序规则.线程中的每个操作都发生在程序顺序后面的该线程中的每个操作之前."

我相信"程序顺序"是指源代码.

我的问题:假设这个规则,我想知道什么指令可能实际重新排序.

"行动"定义如下:

Java内存模型是根据操作指定的,包括对变量的读取和写入,监视器的锁定和解锁,以及启动和连接线程.JMM定义了在程序中的所有操作之前调用的部分排序.为了保证执行动作B的线程可以看到动作A的结果(A和B是否出现在不同的线程中),必须在A和B之间的关系之前发生.在没有发生之前在两个之间进行排序操作,JVM可以随意重新排序.

其他提到的订单规则是:

  • 监控锁定规则.监视器锁定上的解锁发生在同一监视器锁定的每个后续锁定之前.
  • 易变变量规则.对每个后续读取同一字段之前发生对易失性字段的写入.
  • 线程启动规则.在线程上调用Thread.start会在启动线程中的每个操作之前发生.
  • 线程终止规则.线程中的任何操作都发生在任何其他线程检测到该线程已终止之前,可以通过成功从Thread.join返回,也可以通过Thread.isAlive返回false.
  • 中断规则.另一个线程上的线程调用中断发生在被中断的线程检测到中断之前(通过抛出InterruptedException,或者调用isInterrupted或中断).
  • 终结者规则.对象的构造函数的结束发生在该对象的终结器的开始之前.
  • 及物.如果A发生在B之前,B发生在C之前,那么A发生在C之前.

java concurrency multithreading java-memory-model

51
推荐指数
1
解决办法
1万
查看次数

编译时的Java代码转换

在将源代码传递给编译器之前,我想在编译时转换 java源代码.换句话说,我想创建一个能够转换的预处理器

"bla bla bla" 
Run Code Online (Sandbox Code Playgroud)

进入任何其他代码,如:

new MyClass("bla", 3) 
Run Code Online (Sandbox Code Playgroud)

我的实际动机是进行字符串加密,如此处所述

有些人建议编写自定义注释处理器,但据我理解注释:

  • 它们可用于生成新的类文件,但不能在传递给编译器之前转换现有代码
  • 它们似乎在包,类或方法级别工作,但不是方法体/实现.

有些人建议使用Spoon或ObjectsWeb ASM等框架,但这些框架在现有代码库中学习和部署似乎很复杂.

我茁壮成长为两种方法找到一个简单的java代码预处理示例.

有没有人看到任何聪明的方法进行代码转换,而没有用多个常春藤模块完全改变现有的大型代码库?注释似乎是最好的方法,但我不明白该怎么做.

java compilation code-translation

25
推荐指数
2
解决办法
3886
查看次数

HBase扫描很慢

问题

我正在尝试与Phoenix建立二级索引.索引创建需要几个小时.这似乎是由于HBase扫描速度慢,因为我注意到以下性能:

  • 我可能需要2个小时来扫描表,而其他开发人员报告了几分钟的大表(1亿行).
  • HBase shell能够计算大约的行数.速率为每秒10.000,这意味着3800s(> 1小时!)来计算该表的所有行.

使用HBase shell和Java扫描程序.

注意:GET(通过rowkey)操作实现了良好的性能(约0.5秒).


上下文

  • 3800行/ 1000列/单列系列/ 96Go,带GZ压缩.
  • Cluster有6个节点(126Go RAM,24个核心),有5个区域服务器.
  • Hortonworks数据平台2.2.0

故障排除

基于HBase书籍(http://hbase.apache.org/book.html#performance),这是我已经检查过的内容:

1)硬件

  • IO(磁盘)
    • NMon称磁盘永远不会超过80%,最常见的是0到20%
    • Top说HBase JVM没有交换(检查5个RS中的2个)
  • IO(网络):每个节点活动接口站在同一个交换机上(所有第二个被动接口都插在不同的交换机上)

2)JVM

  • GC暂停OK(每分钟左右暂停几毫秒)
  • 堆看起来不错(在极限附近没有达到峰值太长)
  • CPU令人惊讶的低:从不超过10%
  • 主题:
    • 活动线程(10"RpServe.reader = N"+其他一些)显示没有争用
    • 许多停放的线程什么都不做(60"DefaultRpcServer.handler = n",大约15个其他)
    • 没有任何线程状态的巨大IPC客户端列表

3)数据

  • 使用Hive + completebulkload批量加载.
  • 地区数量:
    • 13个区域意味着每个RS有2到3个大区域,这是预期的.
    • 在强制进行主要压缩后,扫描性能保持不变.
    • 区域大小相当同质:11个区域为4,5Go(+/- 0.5),2个区域为2,5Go

4)HBase配置

  • 大多数配置保持不变.

    • HBase env仅指示JMX控制台的端口
    • HBase-site对Phoenix的设置很少
  • 一些对我来说看起来不错的params

    • hbase.hregion.memstore.block.multiplier
    • hbase.hregion.memstore.flush.size:134217728 bytes(134Go)
    • Xmx的Xmn比率:.2Xmn最大值:512Mb Xms:6144m
    • hbase.regionserver.global.memstore.lowerLimit:0.38
    • hbase.hstore.compactionTreshold:3
    • hfile.block.cache.size:0.4(块缓存大小占堆的AS%)
    • 最大HStoreFile(hbase.hregion.max.filesize):10 go(10737418240)
    • 客户端扫描程序缓存:100行zookeeper超时:30秒
    • 客户端最大密钥值大小:10mo
    • hbase.regionserver.global.memstore.lowerLimit:0.38
    • hbase.regionserver.global.memstore.upperLimit:0.40
    • hstore阻止storefiles:10
    • hbase.hregion.memstore.mslab.enabled:
    • 启用hbase.hregion.majorcompaction.jitter:0.5
  • 尝试以下配置更改而不会对性能产生任何影响

    • hbase-env.sh:尝试增加HBASE_HEAPSIZE = 6144(因为它默认为1000)
    • hbase-site.xml:
      • hbase.ipc.server.callqueue.read.ratio:0.9
      • hbase.ipc.server.callqueue.scan.ratio:0.9

5)日志没有任何用处

cat hbase-hbase-master-cox.log …

hbase phoenix

14
推荐指数
1
解决办法
5841
查看次数

如何在最终编译之前使用java注释修改源代码?

我从apt工具页面读到,可以创建AnnotationProcessors来生成新的派生文件(源文件,类文件,部署描述符等).我正在寻找这样做的例子.

我需要在编译时对所有带注释的字符串进行编码,以便读取类文件不允许读取静态字符串:

基本代码:

String message = (@Obfuscated "a string that should not be readable in class file");
Run Code Online (Sandbox Code Playgroud)

应该重新修改为:

String message = new ObfuscatedString(new long[] {0x86DD4DBB5166C13DL, 0x4C79B1CDC313AE09L, 0x1A353051DAF6463BL}).toString();
Run Code Online (Sandbox Code Playgroud)

基于ObfuscatedString.obfuscate(String)TrueLicense框架的静态方法,处理器可以生成代码以替换带注释的字符串.实际上,这个方法生成字符串"new ObfuscatedString([numeric_code]).toString()".在运行时,ObfuscatedString的toString()方法能够返回在数字代码中编码的字符串.

关于如何编写AnnotationProcessor的process()方法来编辑带注释的代码的任何想法?

提前致谢,

java apt annotations

11
推荐指数
1
解决办法
2647
查看次数

使用文本文件作为Spark流媒体源进行测试

我想为消耗水槽源的火花流应用程序编写一个测试.

http://mkuthan.github.io/blog/2015/03/01/spark-unit-testing/建议使用ManualClock,但目前读取文件并验证输出对我来说已经足够了.

所以我希望使用:

JavaStreamingContext streamingContext = ...
JavaDStream<String> stream = streamingContext.textFileStream(dataDirectory);
stream.print();
streamingContext.awaitTermination();
streamingContext.start();
Run Code Online (Sandbox Code Playgroud)

不幸的是它没有打印任何东西.

我试过了:

  • dataDirectory ="hdfs:// node:port/absolute/path/on/hdfs /"
  • dataDirectory ="file:// C:\\ absolute \\ path \\ on \\ windows \\"
  • 在程序开始之前在目录中添加文本文件
  • 在程序运行的目录中添加文本文件

什么都行不通.

有什么建议从文本文件中读取?

谢谢,

马丁

testing spark-streaming

7
推荐指数
2
解决办法
7512
查看次数

如何让JTable停留在已编辑的单元格上

如果有人编辑JTable的单元格内容并按Enter键,则会修改内容并将表格选择移动到下一行.

是否可以禁止JTable在单元格版本之后进入下一行

原因是我的程序使用ListSelectionListener在单元格选择上同步其他一些小部件,我不希望在编辑当前单元格后选择下一行.

java swing jtable tablecelleditor

5
推荐指数
1
解决办法
1160
查看次数

getResource()无法加载jar中的内容

我可以在eclipse中成功加载位于我的src/dir的某个包中的资源.现在,我导出jar(右键单击src,export,jar,并保留默认设置),并且不能在另一个eclipse项目中加载资源.

我通过指示站在相同包名中的类来构建资源的路径:

URL out = getClass().getClassLoader().getResource(packageName(getClass())+"file.glsl");
// out is null when loaded from a jar!!   

protected static String packageName(Class<?> clazz){
    return packageName(clazz.getPackage());
}
protected static String packageName(Package p){
    return c + p.getName().replace('.', c) + c;
}
protected static char c = File.separatorChar;
Run Code Online (Sandbox Code Playgroud)

你看错了吗?我试过了:

  • 的getClass().getResource()方法
  • 的getClass().getClassLoader().getResource()方法
  • 的getClass().getClassLoader().的getResourceAsStream()
  • Thread.currentThread().getContextClassLoader().getResource()方法
  • 在包名称的开头添加/删除'/'字符
  • 使用'/','\'或File.separatorChar,甚至'.',都失败了.

我证实了这一点:

  • jar包含资源(在eclipse项目的"Referenced Libraries"中扩展jar内容)
  • packageName(getClass())+ filename)返回一个干净的名称:"\ org\jzy3d\plot3d\rendering\ddp\algorithms\dual_peeling_init_vertex.glsl"

我无休止地检索一个null:/


编辑:截图和代码,以显示"应该工作"

在此输入图像描述

你可以在这里检索这个SSCCE压缩的eclipse项目

用户类

public class User {
    public static void main(String[] args) {
        Loader pair = new Loader(SomeClass.class, "shade_vertex.glsl");
        System.out.println("found:" + …
Run Code Online (Sandbox Code Playgroud)

java eclipse jar

5
推荐指数
1
解决办法
4774
查看次数

Netbeans Lookup:使用注释定义 ServiceProvider,而不是通过文本/xml 文件

我需要有最简单的方法通过外部 jar 提供接口的实现。我想避免使用文本/xml 文件,因为在重构类或接口名称时它可能会导致错误。

我尝试了 Netbeans Lookup,因为它有一个@ServiceProvider 注释,应该以声明性方式注册实现。

所以我写了一个简单的试用代码,它甚至没有将接口和提供者拆分到不同的jar中,但它仍然无法查找组件:

import org.openide.util.Lookup;
import org.openide.util.lookup.ServiceProvider;

public class LookupTrial {
public static void main(String[] args) {
    IService s = Lookup.getDefault().lookup(IService.class);
    if(s==null)
        throw new RuntimeException("lookup failed");
    else
        s.hello();
}

public interface IService{
    public void hello();
}

@ServiceProvider(service=IService.class)
public class MyImplementation implements IService{
    public MyImplementation(){}

    @Override
    public void hello() {
        System.out.println("hello lookup");
    }
}
}
Run Code Online (Sandbox Code Playgroud)

我是否错误地使用了Lookup?我应该搜索另一个查找库来执行我想要的操作吗?

java lookup netbeans netbeans-platform

5
推荐指数
1
解决办法
2032
查看次数

关于java同步的简单问题

我想使用旧方式(int i ...)循环遍历java List,因为对于给定的i和循环迭代,我想访问相对于i的几个元素.然后我不能使用(对象o:对象)列表迭代器.

在执行时,如何确保没有其他代码可以访问列表?

我试过了

synchronized(path.getPoints()){
    for (int i = 0; i < path.getPoints().size(); i++){
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

其中path是保存列表的对象,也是

synchronized(path){
    for (int i = 0; i < path.getPoints().size(); i++){
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

并且

synchronized(this){
    for (int i = 0; i < path.getPoints().size(); i++){
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

其中"this"是想要在没有同步问题的情况下完全呈现路径的渲染器.

提前致谢,

马丁

java synchronization

2
推荐指数
1
解决办法
221
查看次数

Guava SetMultimap不可序列化(由于不可序列化的WrappedSet)

我经常使用java序列化,这对于存储完整的对象层次结构非常有用.

在尝试序列化SetMultimap时,我得到一个异常,说AbstractMultimap.WrappedSet不可序列化.

番石榴用户如何解决这个问题?

提前致谢,

java guava

2
推荐指数
1
解决办法
1774
查看次数

性能与设计相关的java中的私有/受保护方法

我们正和朋友讨论java代码设计和效率问题.

他认为,出于性能原因,方法最好是私有的,以及在覆盖时最好保持类一致性.

我认为最好保护方法以获得完全的可定制性,并且一旦用户想要改变其部分行为,就应避免浪费时间修改和释放API.

我们知道组合优于继承,所以在这里我主要关注性能比较.

一个简单的测试(见下文)证明父类具有受保护方法的扩展类并不比具有私有方法的父类慢.甚至有时 (我真的不太了解性能变化)更快.

elapsed:8051733.063 microseconds for A (private)
elapsed:8036953.805 microseconds for B (protected)
Run Code Online (Sandbox Code Playgroud)

你认为下面提到的测试足够强大,可以进行比较吗?

public class VerifPerfProtected {
public static void main(String[] args) {
    int ncalls = 1000000000; //10^9
    ChildrenClassA a = new ChildrenClassA();
    ChildrenClassB b = new ChildrenClassB();

    long start = System.nanoTime();
    a.manyCalls(ncalls);
    long stop = System.nanoTime();
    System.out.println("elapsed:" + (stop - start)/1000.0 + " microseconds for A (private)");

    start = System.nanoTime();
    b.manyCalls(ncalls);
    stop = System.nanoTime();
    System.out.println("elapsed:" + (stop - start)/1000.0 + " microseconds …
Run Code Online (Sandbox Code Playgroud)

java private protected

2
推荐指数
1
解决办法
1514
查看次数

在java中索引文本文件

我有一组文本文件提供解析,分析并允许构建模型的信息.有时,该模型的用户想要知道文本文件的哪个部分用于生成给定的模型项.

为此,我正在考虑跟踪行(或字节)id的范围,以便能够在需要时读取相应的文本部分.

我的问题是:我想知道它是否存在任何java Reader能够通过使用开始和停止行(或字节)id而不是从开始和计算行(字节)读取文件来读取文件?

最好的祝福

java indexing text

0
推荐指数
1
解决办法
1770
查看次数