刚刚在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中,抛出已检查异常的方法(异常或其子类型 - 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
在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)
为什么这两种方法同步而其他方法都不同步?
今天我试着重构这个代码,它从目录中的文件中读取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
不能使用类似的方法.
我们有一个移动应用程序,向用户提供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) 很抱歉,如果已经解释过,但我没有在网络中的任何地方找到类似的线程.
今天我在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.添加真实类的屏幕截图(不确定它会解释更多内容,它与我描述的相同)
我在网上进行了一项小型研究并审查了该网站上的相关主题,但答案是矛盾的:有些人说这是不可能的,有些人说这是可能的,但很危险.
目标是将匿名类的对象作为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
.
故事:
几天前,我在考虑基于文件交换的进程间通信.假设进程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 /等?
我需要在hadoop集群中禁用YARN应用程序的并行执行.现在,YARN具有默认设置,因此可以并行运行多个作业.我认为没有这个优点,因为两个工作都运行得慢.
我发现此设置yarn.scheduler.capacity.maximum-applications
限制了最大数量的应用程序,但它会影响提交和运行的应用程序(如文档中所述).我想将提交的应用程序保持在队列中,直到当前正在运行的应用程序未完成.如何才能做到这一点?
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 ×9
hadoop ×2
hadoop-yarn ×2
akka ×1
concurrency ×1
exception ×1
file ×1
filesystems ×1
generics ×1
ipc ×1
java-7 ×1
java-8 ×1
java-io ×1
java-stream ×1
mapreduce ×1
rmi ×1
tomcat ×1
try-catch ×1