假设我有一个由任意方法返回的列表:
List<E> someList = someObject.getList();
Run Code Online (Sandbox Code Playgroud)
someList可以someObject在另一个线程中随时更改.我无权访问someObject,并且someObject.getList()不返回同步或不可变列表实现.
我想迭代someList.不幸的是,由于列表可以更改,通过迭代通常不起作用:
// Sometimes throws ConcurrentModificationException
for(E element : someObject.getList()) {
doSomething(element);
// ...
}
Run Code Online (Sandbox Code Playgroud)
那么如何迭代外来方法返回的列表(而不是线程安全)呢?
考虑以下 C 代码:
#include <stdatomic.h>
struct _opaque;
typedef struct _opaque *opaque;
struct container { _Atomic opaque x; };
struct container get_container();
void consume_opaque(opaque);
void test() {
consume_opaque(get_container().x);
}
Run Code Online (Sandbox Code Playgroud)
编译失败(Clang 16)并出现错误:
error: passing '_Atomic(opaque)' to parameter of incompatible type 'opaque' (aka 'struct _opaque *')
Run Code Online (Sandbox Code Playgroud)
即使在尝试显式转换参数:之后,此代码仍然无法编译(opaque) get_container().x。
相比之下,请考虑以下事项:
#include <stdatomic.h>
struct _opaque;
typedef struct _opaque *opaque;
struct container { _Atomic opaque x; };
struct container *get_container();
void consume_opaque(opaque);
void test() {
consume_opaque(get_container()->x);
}
Run Code Online (Sandbox Code Playgroud)
这编译得很好,编译器显然很乐意进行转换get_container()->x,但get_container().x在容器按值返回的情况下则不然。
为什么会这样呢?如何让编译器在第一个示例中进行转换而不将返回值显式保存get_container() …
我一直试图通过玩转 ASM 中的跳转来了解堆栈映射框架在 Java 中的工作原理。我创建了一个简单的方法来尝试一些东西:(用 Krakatau 拆卸):
L0: ldc 'hello'
L2: astore_1
L3: getstatic Field java/lang/System out Ljava/io/PrintStream;
L6: new java/lang/StringBuilder
L9: dup
L10: invokespecial Method java/lang/StringBuilder <init> ()V
L13: ldc 'concat1'
L15: invokevirtual Method java/lang/StringBuilder append (Ljava/lang/String;)Ljava/lang/StringBuilder;
L18: aload_1
L19: invokevirtual Method java/lang/StringBuilder append (Ljava/lang/String;)Ljava/lang/StringBuilder;
L22: invokevirtual Method java/lang/StringBuilder toString ()Ljava/lang/String;
L25: invokevirtual Method java/io/PrintStream println (Ljava/lang/String;)V
L28: getstatic Field java/lang/System out Ljava/io/PrintStream;
L31: new java/lang/StringBuilder
L34: dup
L35: invokespecial Method java/lang/StringBuilder <init> ()V
L38: ldc 'concat2'
L40: invokevirtual …Run Code Online (Sandbox Code Playgroud) 我有一个类,我想将其放入 a 中TreeSet,它实现Comparable按优先级对它们进行排序。这是一小段:
public abstract class PacketListener implements Comparable<PacketListener> {
public enum ListenerPriority {
LOWEST, LOW, NORMAL, HIGH, HIGHEST
}
private final ListenerPriority priority; // Initialized in constructor
// ... class body ...
@Override
public final int compareTo(PacketListener o) {
return priority.compareTo(o.priority);
}
}
Run Code Online (Sandbox Code Playgroud)
这个想法显然是为了按TreeSet优先级对对象进行排序,使我能够按顺序遍历侦听器。但是,我发现,由于某种原因,我无法PacketListener向设置的对象添加第二个对象。添加两个不同的PacketListener对象后,集合的大小仍为 1。
我不应该使用吗TreeSet?
这个问题说LEA指令可以用来做算术.
据我了解,而不是:
inc eax
mov ecx, 5
mul ecx
mov ebx, eax
Run Code Online (Sandbox Code Playgroud)
我可以简单地写
lea ebx, [(eax + 1) * 5]
Run Code Online (Sandbox Code Playgroud)
LEA版本只是一条指令,而不是4.但是,我不明白LEA如何在没有inc和的情况下进行算术运算mul.
LEA版本在任何方面都更快,或者LEA是否只是在后台运行原始指令?
编辑:这个问题不是关于LEA的目的,而是它如何在内部工作.
我有一个简单的C++类,我正在尝试添加流操作符,因此它可以与cout和一起使用cin
#include <iostream>
namespace testing_namespace {
class test {
friend std::ostream &operator<<(std::ostream &os, const test &o);
friend std::istream &operator>>(std::istream &is, test &o);
public:
void doThing();
private:
int member;
};
}
Run Code Online (Sandbox Code Playgroud)
这是实现文件:
std::ostream &operator<<(std::ostream &os, const testing_namespace::test &o) {
return os << o.member;
}
std::istream &operator>>(std::istream &is, testing_namespace::test &o) {
return is >> o.member;
}
void testing_namespace::test::doThing() {
std::cout << member << " thing" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
我在编译时遇到错误:
In function 'std::ostream& operator<<(std::ostream&, const testing_namespace::test&)':
test.cpp:8:20: error: 'int testing_namespace::test::member' …Run Code Online (Sandbox Code Playgroud) java ×3
arraylist ×1
assembly ×1
atomic ×1
c ×1
c++ ×1
casting ×1
concurrency ×1
friend ×1
jvm-bytecode ×1
namespaces ×1
x86 ×1