小编Ada*_*ker的帖子

了解ConcurrentHashMap计算方法的代码

刚刚在ConcurrentHashMap计算方法中发现了这个奇怪的代码:(第1847行)

public V compute(K key,
                 BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
    ...
    Node<K,V> r = new ReservationNode<K,V>();
    synchronized (r) {   <--- what is this?
        if (casTabAt(tab, i, null, r)) {
            binCount = 1;
            Node<K,V> node = null;
Run Code Online (Sandbox Code Playgroud)

因此代码对仅可用于当前线程的新变量执行同步.这意味着没有其他线程可以竞争这种锁定或导致内存阻塞效应.

这个动作有什么意义?这是一个错误还是会引起一些我不知道的不明显的副作用?

ps jdk1.8.0_131

java multithreading concurrenthashmap

46
推荐指数
3
解决办法
2595
查看次数

为什么捕获检查的异常允许不抛出异常的代码?

在Java中,抛出已检查异常的方法(异常或其子类型 - IOException,InterruptedException等)必须声明throws语句:

public abstract int read() throws IOException;
Run Code Online (Sandbox Code Playgroud)

不声明throws语句的方法不能抛出已检查的异常.

public int read() { // does not compile
    throw new IOException();
}
// Error: unreported exception java.io.IOException; must be caught or declared to be thrown
Run Code Online (Sandbox Code Playgroud)

但是在安全方法中捕获已检查的异常在java中仍然是合法的:

public void safeMethod() { System.out.println("I'm safe"); }

public void test() { // method guarantees not to throw checked exceptions
    try {
        safeMethod();
    } catch (Exception e) { // catching checked exception java.lang.Exception
        throw e; …
Run Code Online (Sandbox Code Playgroud)

java exception try-catch checked-exceptions unchecked-exception

34
推荐指数
3
解决办法
5247
查看次数

Java IO Streams中的同步方法

在Java中,Java 1.0在类中java.io.InputStream有方法

public synchronized void mark(int readlimit) {}
Run Code Online (Sandbox Code Playgroud)

public synchronized void reset() throws IOException {
    throw new IOException("mark/reset not supported");
}
Run Code Online (Sandbox Code Playgroud)

为什么这两种方法同步而其他方法都不同步?

java concurrency multithreading synchronization

25
推荐指数
1
解决办法
1527
查看次数

在Stream API中使用AutoClosable接口

今天我试着重构这个代码,它从目录中的文件中读取id,

Set<Long> ids = new HashSet<>();
for (String fileName : fileSystem.list("my-directory")) {
    InputStream stream = fileSystem.openInputStream(fileName);
    BufferedReader br = new BufferedReader(new InputStreamReader(stream));
    String line;
    while ((line = br.readLine()) != null) {
        ids.add(Long.valueOf(line.trim()));
    }
    br.close();
}
Run Code Online (Sandbox Code Playgroud)

使用流api

Set<Long> ids = fileSystem.list("my-directory").stream()
    .map(fileName -> fileSystem::openInputStream)
    .map(is -> new BufferedReader(new InputStreamReader(is)))
    .flatMap(BufferedReader::lines)
    .map(String::trim)
    .map(Long::valueOf)
    .collect(Collectors.toSet());
Run Code Online (Sandbox Code Playgroud)

然后我发现IO流不会被关闭,我没有看到一种简单的方法来关闭它们,因为它们是在管道内创建的.

有任何想法吗?

upd:示例中的FileSystem是HDFS,Files#lines不能使用类似的方法.

java java-io java-8 java-stream autocloseable

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

如何优化Tomcat for Feed pull

我们有一个移动应用程序,向用户提供Feed.feed tom API是在tomcat上实现的,它并行调用不同的数据源,如Couchbase,MYSQL来呈现内容.简单的代码如下:

Future<List<CardDTO>> pnrFuture = null;
Future<List<CardDTO>> newsFuture = null;

ExecutionContext ec = ExecutionContexts.fromExecutorService(executor);

final List<CardDTO> combinedDTOs = new ArrayList<CardDTO>();

// Array list of futures 
List<Future<List<CardDTO>>> futures = new ArrayList<Future<List<CardDTO>>>();

futures.add(future(new PNRFuture(pnrService, userId), ec)); 
futures.add(future(new NewsFuture(newsService, userId), ec)); 
futures.add(future(new SettingsFuture(userPreferenceManager, userId), ec)); 

Future<Iterable<List<CardDTO>>> futuresSequence = sequence(futures, ec); 

// combine the cards 
Future<List<CardDTO>> futureSum =  futuresSequence.map( 
        new Mapper<Iterable<List<CardDTO>>, List<CardDTO>>() {
            @Override 
            public List<CardDTO> apply(Iterable<List<CardDTO>> allDTOs) { 
                for (List<CardDTO> cardDTOs : allDTOs) {
                    if (cardDTOs != null) {
                        combinedDTOs.addAll(cardDTOs);
                    } 
                } …
Run Code Online (Sandbox Code Playgroud)

java tomcat akka

12
推荐指数
2
解决办法
171
查看次数

关于不兼容的强制转换没有编译器错误

很抱歉,如果已经解释过,但我没有在网络中的任何地方找到类似的线程.

今天我在IDE中打开了一个项目类并看到了一个错误(红色下划线),尽管项目编译成功.

所以,代码是:

public interface DatasourceImplementation<T extends Entity> {
     ....
}

public interface Datasource<T extends Entity> {
     ....
}


public interface DsContext {
    @Nullable
    <T extends Datasource> T get(String name);
}
Run Code Online (Sandbox Code Playgroud)

现在我们将这种方法称为:

DatasourceImplementation dsImpl = getDsContext().get("dsName");
Run Code Online (Sandbox Code Playgroud)

Idea13给了我错误(不兼容的类型) - 我认为这是正确的.

Idea14在此处未显示任何错误.

JDK编译它没有错误 - 这很难过.

必须说,在我们的A接口的项目实现类中总是实现B接口(可能解释为什么Idea14说它没关系),但在我看来这不能证明这种行为是正确的 - 因为通常我可以创建实现A的类并且不会实现B.我想在我的代码中使用静态典型化,我不希望看到运行时类转换异常.

那么,谁在这里错了?

UPD.添加真实类的屏幕截图(不确定它会解释更多内容,它与我描述的相同)

在此输入图像描述

java generics classcastexception java-7

10
推荐指数
1
解决办法
373
查看次数

是否可以在没有外部类的情况下序列化匿名类?

我在网上进行了一项小型研究并审查了该网站上的相关主题,但答案是矛盾的:有些人说这是不可能的,有些人说这是可能的,但很危险.

目标是将匿名类的对象作为RMI方法的参数传递.由于RMI要求,此类必须是可序列化的.这没问题,很容易使类Serializable.

但我们知道内部类的实例包含对外部类的引用(而匿名类是内部类).因此,当我们序列化内部类的实例时,外部类的实例被序列化以及字段.这里是问题出现的地方:外部类不可序列化,更重要的是 - 我不想序列化它.我想要做的只是发送匿名类的实例.

简单示例 - 这是一个RMI服务,其方法接受Runnable:

public interface RPCService {    
    Object call(SerializableRunnable runnable);
}
Run Code Online (Sandbox Code Playgroud)

以下是我想要调用该方法的方法

void call() {
     myRpcService.call(new SerializableRunnable() {             
         @Override
         public Object run {
             System.out.println("It worked!");
         }
     }        
}
Run Code Online (Sandbox Code Playgroud)

如您所见,我想要做的是向另一方发送"动作" - 系统A描述应该在系统B上运行的代码.这就像用Java发送脚本一样.

如果可能的话,我可以很容易地看到一些危险的后果:例如,如果我们从Runnable访问字段或捕获外部类的最终变量 - 我们将遇到麻烦,因为调用者实例不存在.另一方面,如果我在Runnable中使用安全代码(编译器可以检查它),那么我没有看到禁止此操作的原因.

因此,如果有人知道,如何在匿名类中正确覆盖方法writeObject()readObject()方法,或者如何引用外部类transient或者解释为什么在java中不可能,它将非常有用.

UPD 另一个需要考虑的重要事项:外部类不存在于将执行该方法的环境中(系统B),这就是为什么应该完全排除有关它的信息以避免NoClassDefFoundError.

java serialization rmi anonymous-class

9
推荐指数
1
解决办法
3897
查看次数

进程间文件交换:效率和竞争条件

故事:
几天前,我在考虑基于文件交换的进程间通信.假设进程A在其工作期间创建了几个文件,然后进程B读取这些文件.为确保正确写入所有文件,创建一个特殊文件会很方便,该文件的存在将表明所有操作都已完成.

简单的工作流程:
进程A创建文件"file1.txt"
进程A创建文件"file2.txt"
进程A创建文件"processA.ready"

进程B正在等待文件"processA.ready"出现,然后读取file1和file2.

怀疑:
文件操作由操作系统执行,特别是由文件子系统执行.由于Unix,Windows或MacOS的实现可能不同,我不确定文件交换进程间通信的可靠性.即使操作系统能够保证这种一致性,Java中的JIT编译器也可以重新排序程序指令.

问题:
1.操作系统中的文件操作是否有任何实际规范?
2. JIT是否真的允许为单个程序线程重新排序文件操作程序指令?
3.文件交换现在仍然是进程间通信的相关选项,还是无条件地更好地选择TCP/HTTP /等?

java filesystems operating-system ipc file

9
推荐指数
1
解决办法
293
查看次数

如何在YARN中配置垄断FIFO应用队列?

我需要在hadoop集群中禁用YARN应用程序的并行执行.现在,YARN具有默认设置,因此可以并行运行多个作业.我认为没有这个优点,因为两个工作都运行得慢.

我发现此设置yarn.scheduler.capacity.maximum-applications限制了最大数量的应用程序,但它会影响提交和运行的应用程序(如文档中所述).我想将提交的应用程序保持在队列中,直到当前正在运行的应用程序未完成.如何才能做到这一点?

hadoop hadoop-yarn

6
推荐指数
2
解决办法
541
查看次数

以编程方式限制YARN容器

hadoop集群中有10个节点,32GB RAM,一个64GB.

对于这10个节点,节点限制yarn.nodemanager.resource.memory-mb设置为26GB,64GB节点设置为52GB(对于单个reducer,有些作业需要50GB,它们在此节点上运行)

问题是,当我运行需要8GB映射器的基本工作时,32GB节点并行产生3个映射器(26/8 = 3),64GB节点产生6个映射器.由于CPU负载,此节点通常最后完成.

我想以编程方式限制作业容器资源,例如,对于大多数作业,将容器限制设置为26GB.怎么做到呢?

java hadoop mapreduce hadoop-yarn

6
推荐指数
1
解决办法
595
查看次数