Tag: 并发

不要同时在两个线程之间共享相同的套接字

我有大约60个套接字和20个线程,我想确保每个线程每次都在不同的套接字上工作,所以我不想在两个线程之间共享相同的套接字。 在我的SocketManager类中,我有一个后台线程,每60秒运行一次并调用updateLiveSockets()方法。 在updateLiveSockets()方法中,我迭代我拥有的所有套接字,然后通过调用SendToQueue类的send方法SendToQueue ping它们,并根据响应我将它们标记为活动或死亡。 在updateLiveSockets()方法中,我总是需要迭代所有套接字并ping它们以检查它们是活的还是死的。 现在,所有读者线程将同时调用SocketManager类的getNextSocket()方法,以获得下一个可用的套接字以在该套接字上发送业务消息。 所以我有两种类型的消息,我在套接字上发送: 一个是套接字上的ping消息。 这只是从调用SocketManager类中的updateLiveSockets()方法的计时器线程发送的。 其他是套接字上的business消息。 这是在SendToQueue类中完成的。 因此,如果pinger线程正在ping一个套接字以检查它们是否存在,那么没有其他业务线程应该使用该套接字。 类似地,如果业务线程使用套接字在其上发送数据,那么pinger线程不应该ping该套接字。 这适用于所有套接字。 但我需要确保在updateLiveSockets方法中,每当我的后台线程启动时,我们都会ping所有可用的套接字,以便我们可以确定哪个套接字是活的还是死的。 下面是我的SocketManager类: public class SocketManager { private static final Random random = new Random(); private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); private final Map<Datacenters, List> liveSocketsByDatacenter = new ConcurrentHashMap(); private final ZContext ctx = new ZContext(); // … private SocketManager() { connectToZMQSockets(); […]

正确实现按需初始化持有者习惯用法

我有两个版本的“初始化按需持有人习惯用语”: http://en.wikipedia.org/wiki/Initialization-on-demand_holder_idiom http://en.wikipedia.org/wiki/Singleton_pattern#The_solution_of_Bill_Pugh 上述主要区别在于,第一个宣布INSTANCE为私有 ,但第二个宣布INSTANCE为公开 。 请告诉我应该使用哪一个。 对不起,我没有发现在我的应用程序中使用private和public之间的区别: public class Singleton { private int x; public int getX() { return x; } private Singleton () {} private static class LazyHolder { //both private and public works private static final Singleton INSTANCE = new Singleton(); } public static Singleton getInstance() { return LazyHolder.INSTANCE; } } 我唯一要做的就是调用类似Singleton.getInsance().getX() […]

java concurrent Array List访问

我有一个单身的物体。 该对象声明: List players = new ArrayList(); 同一个对象还在此arrayList上指定了4个操作: public List getPlayers() { return players; } // the result of this method can be used in another object as an iterator (or maybe by index-access) 和 public void removePlayer(Player player) { players.remove(player); } public void addPlayer(Player player) { players.add(player); } public boolean isPresent(Player player) { if […]

使用request.getSession()作为锁定对象?

我有一些获取和设置会话属性的java代码: Object obj = session.getAttribute(TEST_ATTR); if (obj==null) { obj = new MyObject(); session.setAttribute(obj); } 为了使这段代码成为线程安全的,我想将它包装在一个synchronized块中。 但是我用什么作为锁定对象呢? 使用会话是否有意义? synchronized (session) { Object obj = session.getAttribute(TEST_ATTR); if (obj==null) { obj = new MyObject(); session.setAttribute(obj); } }

Java在两个线程之间共享一个变量

我有两个主题。 一个调用修改变量的类的update方法。 另一个调用读取变量的类的update方法。 只有一个线程写入,一个(或多个)线程读取该变量。 由于我不熟悉multithreading,因此在并发方面我需要做什么? public class A { public int variable; // Does this need to be volatile? // Not only int, could also be boolean or float. public void update() { // Called by one thread constantly ++variable; // Or some other algorithm variable = complexAlgorithm(); } } public class B { public […]

使用volatile原语而不是primefaces变量有什么区别?

可能重复: Java:volatile boolean vs AtomicBoolean 什么时候使用volatile原语(例如boolean , integer或long )而不是AtomicBoolean , AtomicInteger或AtomicLong ,反之亦然?

Java,在multithreadingevnironments中通过散列统一划分传入的工作

我已经实现了一个java代码来执行传入任务(作为Runnable ),其中n个Threads基于他们的hashCode模块nThreads 。 理想情况下,工作应该在这些线程中一致地传播。 具体来说,我们将dispatchId作为每个Task的字符串。 这是这个java代码片段: int nThreads = Runtime.getRuntime().availableProcessors(); // Number of threads Worker[] workers = new Worker[nThreads]; // Those threads, Worker is just a thread class that can run incoming tasks … Worker getWorker(String dispatchId) { // Get a thread for this Task return workers[(dispatchId.hashCode() & Integer.MAX_VALUE) % nThreads]; } 重要提示:在大多数情况下,dispatchId是: String dispatchId […]

假设我知道我将在x64 cpu上运行,我可以忽略哪些JVM同步实践?

我知道JVM内存模型是为CPU的最小公分母而设计的,因此它必须假设JVM可以运行的最弱的cpu模型(例如ARM)。 现在,考虑到x64具有相当强大的内存模型,假设我知道我的程序只能在64位x86 CPU上运行,我可以忽略哪些同步实践? 当我的程序通过虚拟化运行时,这也适用吗? 例: 众所周知,JVM的内存模型需要同步对long和double的读/写访问,但可以假设其他32位原语(如int,float等)的读/写是primefaces的。 但是,如果我知道我在64位x86机器上运行,我是否可以忽略使用long / double上的锁定知道cpu将自动读取/写入64位值并保持它们不稳定(就像我对int / floats一样) )?

线程对象在哪里创建? 堆栈还是堆?

当我说出类似的话: Thread t1 = new Thread(); 它是在堆还是堆栈上创建它?

LongAdder的表现如何比AtomicLong更好

我看到Java的AtomicInteger如何在内部使用CAS(比较和交换)操作。 基本上,当多个线程尝试更新该值时,JVM在内部使用底层CAS机制并尝试更新该值。 如果更新失败,则再次尝试使用新值但从不阻止。 在Java8中,Oracle引入了一个新的类LongAdder ,它在高争用下似乎比AtomicInteger表现更好。 一些博客文章声称LongAdder通过维护内部单元格表现更好 – 这是否意味着LongAdder在内部聚合值并在以后更新它? 你能帮我理解LongAdder的工作原理吗?