小编Mia*_*ach的帖子

为什么ConcurrentHashMap不能锁定每个桶?

我们知道,java的ConcurrentHashMap有许多内部锁,每个内部锁保护桶数组的某些区域.

一个问题是:为什么我们不能为每个桶创建一个锁

已经提出了类似问题:Java ConcurrentHashMap中增加分区数量的缺点?

根据答案,有几个原因:

  1. 同时运行的最大线程数受处理器核心数量的限制.它是否正确? 我们是否总是声明如果我们有8核处理器,我们在ConcurrentHashMap中不需要超过8个锁定区域?

  2. 浪费L2缓存.为什么?

  3. 浪费了记忆.看起来这是因为额外的锁创建.

还有其他原因吗?

java concurrency multithreading concurrenthashmap

16
推荐指数
2
解决办法
2861
查看次数

关于java多线程的一些问题,

我有一些关于Java多线程问题的问题.请尽可能多地为我提供帮助.

0)假设我们有2个银行账户,我们需要以线程安全的方式在它们之间转账.即

accountA.money += transferSum; 
accountB.money -= transferSum; 
Run Code Online (Sandbox Code Playgroud)

存在两个要求:

  1. 没有人应该能够看到操作的中间结果(即一个总和增加,但其他没有减少)
  2. 在操作过程中不应阻止读取访问(即在操作过程中应显示帐户总和的旧值)

你能就此提出一些想法吗?

1)假设2个线程通过synchronized方法或使用显式锁来修改某个类字段.无论同步如何,都不能保证线程可以看到该字段,通过NOT synchronized方法读取它.- 这是对的吗?

2)通过notify方法唤醒的线程可以等待锁定多长时间?假设我们有这样的代码:

synchronized(lock) {  
    lock.notifyall();   
    //do some very-very long activity  
    lock.wait() //or the end of synchronized block  
}  
Run Code Online (Sandbox Code Playgroud)

我们可以说至少有一个线程会成功并抓住锁吗?由于某些超时,信号会丢失吗?

3)来自Java Concurrency Book的引文:

"单线程执行程序还提供了足够的内部同步,以保证任务所做的任何内存写入对后续任务都是可见的;这意味着对象可以安全地限制在"任务线程"中,即使该线程可能会被另一个时间替换掉时间."

这是否意味着,在单线程执行程序,执行剩下的代码的唯一线程安全的问题是数据的比赛,我们可以放弃volatile变量,而忽略所有的知名度的问题?它看起来像是解决大部分并发问题的通用方法.

4)所有标准的getter和setter都是原子的.如果字段标记为volatile,则无需同步它们.- 这是对的吗?

5)静态字段和静态块的启动由一个线程完成,因此不需要同步.- 这是对的吗?

6)为什么一个线程如果通过wait()方法离开锁定就需要通知其他人,但是如果它通过退出synchronized块而离开锁定则不需要这样做?

java concurrency multithreading

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

断言两个列表在Spock框架中是相同的

我使用Spock框架测试我的应用程序,测试是用Groovy编写的.

作为一些方法评估的结果,我有一个对象列表.我想测试这个列表是否与我期望的列表相同.我编码了以下内容:

def expectedResults = [ ... ] //the list I expect to see
def isEqual = true;

when:
def realResults = getRealResultsMethod() //get real results in a list here
expectedResults.each {isEqual &= realResults.contains(it)}
then:
isEqual
0 * errorHandler.handleError(_) //by the way assert that my errorHandler is never called
Run Code Online (Sandbox Code Playgroud)

这是我第一次使用Groovy的经历,所以可能是我错过了什么?

PS

令我困惑的是Groovy和Spock中的'equals'运算符.给定Java ArrayList或Java数组,equals运算符只是标识运算符:equals is ==.在Groovy中,据我所知,默认等于运算符实际上是等于(在此处形成:http://groovy.codehaus.org/Differences+from+Java).但是Groovy List或Set的'等于'是什么?

UPDATE

更确切地说.我想找出两个列表有相同的对象,两个列表都没有额外的对象,顺序无关紧要.例如:

list=[1,5,8]

list1=[5,1,8]    
list2=[1,5,8,9]

println(list == list1) //should be equal, if we use == not equal    
println(list == list2) …
Run Code Online (Sandbox Code Playgroud)

java groovy spock

10
推荐指数
2
解决办法
2万
查看次数

Oracle PL Sql Developer找不到我的tnsnames.ora文件

我有一个来自我之前工作场所的Oracle tnsnames.ora文件.我想在另一台计算机上使用我新安装的PL SQL Developer来解决它.我已将文件复制到..ORACLE/product/11.2.0/client_32/NETWORK/ADMIN中,但PL SQL Developer找不到它.

它启动时没有向我显示任何数据库选择.在About-> i-> TNSNames中,我看不到任何行

我在Tools-> Preferences-> Database - > ...中找到了许多建议,但我的首选项中没有Database选项卡.

我该如何解决?

tnsnames plsqldeveloper

10
推荐指数
3
解决办法
10万
查看次数

泛型混淆:欺骗编译器

考虑一下代码:

public class GenericsConfusion {
    public static <T> Class<T> get(Class<T> clazz) {
        Map<Class, Class> map = new HashMap<Class, Class>();
        map.put(Integer.class, String.class);
        return map.get(clazz);
    }

    public static void main(String[] args) {
        Class<Integer> clazz = get(Integer.class);
        System.out.println(clazz);
    }
}
Run Code Online (Sandbox Code Playgroud)

它编译和运行完美.我们的想法是在get方法中返回与输入类具有相同类型参数的类.但由于地图的存在,它被打破了.是的,我知道在运行时会删除类型参数信息,因此如果没有类型参数,则此代码完全有效.另外我知道我可以通过指定修复它Map<Class<T>, Class<T>>但事实是在方法签名中我有类型参数,并且它们在编译时没有帮助我.

这是滥用某些概念吗?

或者它是Java泛型的缺点?

或者它完全可以,我误解了类型参数的想法?

java generics

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

应用程序打印"侦听传输dt_socket地址:5005"并且不会停止

我用典型的参数开始代码执行:

java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005 myPackage.myMainClassname
Run Code Online (Sandbox Code Playgroud)

应用程序启动,打印"侦听传输dt_socket地址:5005",然后......更进一步!没有任何等待连接的企图.我可以在执行期间连接到它并且调试本身也可以工作.但为什么应用程序不等待调试器的连接?

在我的配置中看起来有些东西坏了,但我无法找出根本原因.我尝试了几种方法来指定调试设置,不同的端口,以管理员身份运行,关闭防火墙 - 没有任何帮助.

java debugging remote-debugging

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

Maven Install插件:参数文件丢失或无效

我有一个本地jar,我想在我的项目中使用它.有很多方法可以做到:只需手动安装到本地仓库,使用父pom中的脚本,使用系统范围,使用本地repo声明.

我决定使用Maven Install插件将jar安装到repo中.这是一个配置:

    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-install-plugin</artifactId>
        <version>2.3.1</version>
        <executions>
            <execution>
                <phase>initialize</phase>
                <goals>
                    <goal>install-file</goal>
                </goals>
                <configuration>
                    <groupId>jacob</groupId>
                    <artifactId>jacob</artifactId>
                    <version>1.0</version>
                    <packaging>jar</packaging>
                    <file>${basedir}\lib\jacob.jar</file>
                </configuration>
            </execution>
        </executions>
    </plugin>
Run Code Online (Sandbox Code Playgroud)

我尝试以多种方式运行它: mvn初始化安装:install-file mvn initialize mvn install:install-file

但是我一直有例外:

[错误]无法执行目标org.apache.maven.plugins:maven-install-plugin:2.3.1:项目上的install-file(default-cli)MYPROJECTNAME:目标org.apache.maven的参数'file'.插件:maven-install-plugin:2.3.1:安装文件丢失或无效 - >

我只想找出它为什么不起作用?看起来我被阶段和目标弄糊涂了..

最后,我采用了另一种方式:我将它放入我的父POM中,但为什么它与父母一起使用并且不能与孩子一起工作?

jar maven

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

合并排序连接在 Spark 中如何工作以及为什么会抛出 OOM?

我想深入了解Spark中合并排序连接的概念。我理解总体思路:这与合并排序算法的方法相同:采用 2 个排序数据集,比较第一行,写入最小的行,重复。我也了解如何实现分布式合并排序。

但我不明白它是如何在 Spark 中实现分区和执行器概念的。

这是我的看法。

  1. 鉴于我需要连接 2 个表 A 和 B。表是通过 Spark SQL 从 Hive 读取的,如果这很重要的话。
  2. 默认情况下 Spark 使用 200 个分区。
  3. 然后 Spark 将计算连接键范围(从 minKey(A,B) 到 maxKey(A,B) )并将其分成 200 个部分。两个数据集均按关键范围分为 200 个部分:A 分区和 B 分区。
  4. 与相同键相关的每个 A 分区和每个 B 分区都被发送到同一个执行器,并在那里彼此分开排序。
  5. 现在,200 个执行程序可以加入 200 个 A 分区和 200 个 B 分区,并保证它们共享相同的密钥范围。
  6. 连接通过合并排序算法进行:从 A 分区中获取最小键,与 B 分区中的最小键进行比较,写入匹配或迭代。
  7. 最后,我有 200 个已连接的数据分区。

是否有意义?

问题: 按键倾斜。如果某个键范围包含数据集键的 50%,则某些执行器将受到影响,因为太多行将进入同一分区。当尝试对内存中太大的 A 分区或 B 分区进行排序时,它甚至可能因 OOM 而失败(我不明白为什么 Spark 无法像 Hadoop 那样对磁盘溢出进行排序?..)或者它可能会失败,因为它尝试读取两个分区都放入内存中进行连接?

所以,这是我的猜测。您能纠正我并帮助理解 Spark 的工作方式吗?

apache-spark

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

初始化变量的方式有所不同:float f = 100; 或浮动f = 100f?

Java的.

我初始化变量的方式有区别吗:

float f = 100; //implies a cast from integer to float
Run Code Online (Sandbox Code Playgroud)

要么

float f = 100f; //simply a float initialization
Run Code Online (Sandbox Code Playgroud)

结果会有所不同吗?

在这里,我尝试使用非常大的浮子,但看起来精度的损失是相同的.

float f1 = (float)2000000000;
float f2 = (float)2000000050;
float f3 = 2000000000f;
float f4 = 2000000050f;
System.out.println(f1 + " " + f2 + " " + (f1==f2) + " " + f3 + " " + f4 + " "+ (f3==f4) );
Run Code Online (Sandbox Code Playgroud)

- > 2.0E9 2.0E9 true 2.0E9 2.0E9 true

与双打有什么区别?

java floating-point

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

volatile,final和synchronized之间安全发布的差异

给定具有变量x的A类.变量x在类构造函数中设置:

A() {
x = 77;
}
Run Code Online (Sandbox Code Playgroud)

我们想将x发布到其他一些线程.考虑以下3个变量x线程安全(?)发布的情况:

1)x是最终的

2)x是易变的

3)x在同步块中设置

synchronized(someLock) {
A a  = new A();
a.x = 77;
}
Run Code Online (Sandbox Code Playgroud)

Thread2只打印x:

 System.out.println(a.x);
Run Code Online (Sandbox Code Playgroud)

问题是:是否可以观察到Thread2打印的'0'?或者JMM保证将打印'77'或者在所有3种情况下都会抛出NPE?

java concurrency

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