小编Rei*_*ica的帖子

为什么在静态初始化程序中使用lambda的并行流导致死锁?

我遇到了一个奇怪的情况,在静态初始化程序中使用带有lambda的并行流看似永远没有CPU利用率.这是代码:

class Deadlock {
    static {
        IntStream.range(0, 10000).parallel().map(i -> i).count();
        System.out.println("done");
    }
    public static void main(final String[] args) {}
}
Run Code Online (Sandbox Code Playgroud)

这似乎是此行为的最小再现测试用例.如果我:

  • 将块放在main方法而不是静态初始化器中,
  • 删除并行化,或
  • 删除lambda,

代码立即完成.谁能解释这种行为?这是一个错误还是这个意图?

我正在使用OpenJDK版本1.8.0_66-internal.

java deadlock fork-join java-8 java-stream

82
推荐指数
3
解决办法
4222
查看次数

Stream.sorted().limit()的性能

Java流体育运动都sortedlimit方法,它们分别返回流的分类版本,并只返回返回一个流的项目的指定数量的流.当这些操作连续应用时,例如:

stream.sorted().limit(qty).collect(Collectors.toList())
Run Code Online (Sandbox Code Playgroud)

排序是以对项目进行排序qty还是整个列表排序的方式执行的?换句话说,如果qty是固定的,这个操作是在O(n)吗?文档没有单独指定这些方法的性能或相互结合使用.

我问的原因是这些操作的明显必要实现是排序然后限制,花时间?(n * log(n)).但是这些操作可以一起执行,O(n * log(qty))智能流式框架可以在执行之前查看整个流以优化这种特殊情况.

java sorting time-complexity java-8 java-stream

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

如何上限自我指涉类型?

我有可以对自己的类型执行操作的东西(比如上下文,数字):

interface Number<N> {
    N add(N to);
}
class Int implements Number<Int> {
    Int add(Int to) {...}
}
Run Code Online (Sandbox Code Playgroud)

和作用于某个上限的所有子类型的actor:

interface Actor<U> {
    <E extends U> E act(Iterable<? extends E> items);
}
Run Code Online (Sandbox Code Playgroud)

我想创建一个在任何数字类型上多态化的actor:

class Sum implements Actor<Number> {
    <N extends Number<N>> N act(Iterable<? extends N> items) {...}
}
Run Code Online (Sandbox Code Playgroud)

现在,显然这不起作用,因为Number并且Number<N>不一样.实际上,由于Number不将实现者的类型参数约束为其自己的类型,因此这样的actor无法工作.但是我一般不关心Numbers 操作- 我对我的功能只对某些类型的数字工作感到满意N extends Number<N>

作为替代方案,我可以声明:

interface Actor<E> {
    E act(Iterable<? extends E> items);
}

class Sum<N extends Number<N>> implements Actor<N> {
    N act(Iterable<? …
Run Code Online (Sandbox Code Playgroud)

java generics

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

lambda上的LambdaConversionException在交集类型中采用第二种类型

在交集类型中将方法引用应用于第二种类型时,我遇到了一个非常奇怪的问题.这是一个最小的测试用例:

class LambdaTest {

    interface A {}

    interface B {
        B doIt();
    }

    static class AB implements A, B {
        public B doIt() {
            return this;
        }
    }

    static <E extends A & B> void run(E e) {
        Collections.singleton(e).stream().map(B::doIt);
    }

    public static void main(String[] args) {
        run(new AB());
    }
}
Run Code Online (Sandbox Code Playgroud)

此代码编译但run在运行时失败并出现错误:

java.lang.invoke.LambdaConversionException:无效的接收器类型接口LambdaTest $ A; 不是实现类型接口LambdaTest $ B的子类型

显式指定lambda的类型时甚至会发生此问题:

static <E extends A & B> void run(E e) {
    final Function<E, B> doIt = B::doIt;
    Collections.singleton(e).stream().map(doIt);
} …
Run Code Online (Sandbox Code Playgroud)

java lambda java-8

10
推荐指数
0
解决办法
93
查看次数

为什么ThreadLocalRandom实现如此奇怪?

这个问题关注ThreadLocalRandomOpenJDK版本1.8.0的实现.

ThreadLocalRandom提供每线程随机数生成器,没有Random强加的同步开销.最明显的实现(IMO)将是这样的,它似乎保持向后兼容性而没有太多复杂性:

public class ThreadLocalRandom extends Random {
    private static final ThreadLocal<ThreadLocalRandom> tl =
        ThreadLocal.withInitial(ThreadLocalRandom::new);
    public static ThreadLocalRandom current() {
        return tl.get();
    }
    // Random methods moved here without synchronization
    // stream methods here
}

public class Random {
    private ThreadLocalRandom delegate = new ThreadLocalRandom();
    // methods synchronize and delegate for backward compatibility
}
Run Code Online (Sandbox Code Playgroud)

但是,实际的实现是完全不同的,非常奇怪:

  • ThreadLocalRandomRandom逐字复制一些方法,稍作修改; 当然,大部分代码都可以重用.
  • Thread 存储种子和用于初始化`ThreadLocalRandom的探测变量,违反封装;
  • ThreadLocalRandom使用Unsafe访问的变量Thread,我想是因为这两个类在不同的包却状态变量必须是私有的Thread- Unsafe是因为封装违反唯一必要的;
  • ThreadLocalRandom将其下nextGaussian一个存储在静态ThreadLocal而不是实例变量 …

java random implementation

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

涉及多个表的外键约束

我在 Postgres 9.3 数据库中有以下场景:

  • 表 B 和 C 参考表 A。
  • 表 C 有一个引用表 B 的可选字段。

我想确保对于引用表 B 的表 C 的每一行,cba = ca 也就是说,如果 C 引用了 B,那么两行都应该指向表 A 中的同一行。

  • 我可以重构表 C,以便如果指定了 cb,则 ca 为空,但这会使连接表 A 和 C 的查询变得笨拙。
  • 我也许还可以让表 B 的主键包括它对表 A 的引用,然后让表 C 对表 B 的外键包括表 C 对表 A 的引用,但我认为这种调整太笨拙而无法证明好处的合理性。
  • 我认为这可以通过在表 C 上插入/更新之前运行并拒绝违反指定约束的操作的触发器来完成。

在这种情况下,是否有更好的方法来强制执行数据完整性?

postgresql database-design referential-integrity constraints foreign-keys

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

在条件中分配多个val

在Java中,我经常发现自己在条件的每个分支中分配多个最终变量,如下所示:

final _ x;
final _ y;
if (_) {
  x = _;
  y = _;
} else {
  x = _;
  y = _;
}
Run Code Online (Sandbox Code Playgroud)

在Scala中我知道可以使用该技术分配单个val:

val x = {
  if (_) {
    _;
  } else {
    _;
  }
}
Run Code Online (Sandbox Code Playgroud)

实际上,可以修改上述方法以通过使块返回与变量模式匹配的元组来分配多个变量,例如:

{
  if (_) {
    _;
  } else {
    _;
  }
} match { case (x, y) => _ }
Run Code Online (Sandbox Code Playgroud)

但我发现这种语法很尴尬.有没有更简单的方法,理想情况下类似于Java代码,做我想要的?

scala

4
推荐指数
1
解决办法
677
查看次数

stream/fork-join如何通过线程安全地访问数组?

Streams和fork-join都提供了并行化访问数组的代码的功能.例如,Arrays.parallelSetAll主要通过以下行实现:

IntStream.range(0, array.length).parallel()
    .forEach(i -> { array[i] = generator.applyAsLong(i); });
Run Code Online (Sandbox Code Playgroud)

另外,文档RecursiveAction,叉-join框架的一部分,包含以下示例:

static class SortTask extends RecursiveAction {
    final long[] array; final int lo, hi;
    ...
    void merge(int lo, int mid, int hi) {
        long[] buf = Arrays.copyOfRange(array, lo, mid);
        for (int i = 0, j = lo, k = mid; i < buf.length; j++)
            array[j] = (k == hi || buf[i] < array[k]) ?
                buf[i++] : array[k++];
    }
}
Run Code Online (Sandbox Code Playgroud)

最后,从数组创建的并行流以多个线程访问数组(代码太复杂,无法在此汇总).

所有这些示例似乎都是对数组进行读取或写入,而没有任何同步或其他内存障碍(据我所知).我们知道,完全临时的多线程数组访问是不安全的,因为不能保证读取反映另一个线程中的写入,除非读取和写入之间存在先发生关系.实际上,这些Atomic...Array类是专门为解决这个问题而创建的.但是,鉴于上面的每个例子都在标准库或其文档中,我认为它们是正确的.

在这些例子中,有人可以解释一下哪种机制可以保证阵列访问的安全性?

java arrays multithreading java-8

3
推荐指数
1
解决办法
230
查看次数

使用Scalaz自定义半群类时出现问题

scalaz.std.MapInstances声明任何值为a的地图Semigroup本身就是a Monoid.由于IntSemigroup,下面的代码工作:

def merge[K](maps : Iterator[Map[K, Int]]) : Map[K, Int] = maps.reduce(_ |+| _)
Run Code Online (Sandbox Code Playgroud)

但是,我很惊讶以下代码不起作用:

class Num(value : Int) extends Semigroup[Num] {
    def append(x : Num, y : Num): Num = new Num(x.value + y.value)
}

def merge[K](maps : Iterator[Map[K, Num]]) : Map[K, Num] = maps.reduce(_ |+| _)
Run Code Online (Sandbox Code Playgroud)

任何人都可以向我解释为什么值为我的自定义Semigroup类的地图不被视为Monoids?

scala scalaz

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