×

单例模式线程安全问题 线程安全 线程

单例模式的饿汉模式为啥是线程安全的?如何使ArrayList 线程安全

admin admin 发表于2022-07-13 12:19:18 浏览108 评论0

抢沙发发表评论

单例模式的饿汉模式为啥是线程安全的

多线程主要使用CPU,而内存是线程冲突发生的地方。记忆是您放置对象的位置。so -so -call不安全是数据的特征。这是一个案例。邪恶的人是提前建造的,这次将不再有示例。当懒惰的人时,当请求到来时,它可能会同时处理多个请求并创建多个实例。

如何使ArrayList 线程安全

1. 1.使用同步关键字; 2.使用collections.synchronizedlist();如下:如果您创建的代码如下:列表“ data = newarraylist”(); 。 SynChronizedList(),例如:列表“ data = collections.synchronizedlist(newArrayList”());其他都没有改变,使用的方法几乎与arraylist相同。您可以参考API文档;附加的arraylist和linkedlist;这两个是在接口列表下实现的。他们使用相同的用法,但是所使用的地方有些不同。 ArrayList适合使用大量随机访问。 LinkedList适合在表中插入和删除。所有都是非线程安全性。该解决方案与上述相同(为了避免线程安全性,上述方法,尤其是第二种方法实际上是非常耗时的)。第二,定义mylincedlistextendsladendlendelist类以实现同步linkedlist.addfirst();和removelast();方法! myLinkedListList = newmylinkedlist(); ListListProxy = Collections.SynchronizedList(list);使用ListProcxy方法或myLinkedList来实现同步。

如何让Java以光的速度跨线程通信


一个比Disruptor吞吐量等性能指标更好的框架,使用Railway算法,将线程之间的消费发送参考现实生活中火车在站点之间搬运货物。
目标起始于一个简单的想法:创建一个开发人员友好的,简单的,轻量级线程间的通信框架,无需使用任何锁,同步器,信号量,等待,通知以及没有队列,消息,事件或任何其它并发特定的语法或工具。
只是一个Java接口接受到POJO以后在其背后实现这个通信,这个主意很类似Akka的Actors,但是它也许是有点矫枉过正,特别是对于单个多核计算机上线程间的通信优化必须是轻量的。
Akka的伟大之处是跨进程通信,特别是Actor是能够跨越不同JVM节点实现分布式通信。
无论如何,你可能觉得使用Akka在一个小型项目上有些过度,因为你只需要线程之间的通信,但是你还是想使用类似Actor这种做法模式。
该文章作者使用了动态代理 堵塞队列和一个缓存的线程池创建了这个解决方案,如图:
SPSC队列是一个Single Producer/Single Consumer 队列(单生产者/单消费者),而MPSC是一个Multi Producer/Single Consumer队列。
Dispatcher线程从Actor线程接受到消息,然后发送到相应的SPSC中。
Actor线程从接受的消息中使用数据,调用相应的actor类的方法,Actor实例都是发送消息给MPSC队列,然后再从Actor线程那里得到消息。
下面是ping-pong案例:
public interface PlayerA (
void pong(long ball); //send and forget method call
}
public interface PlayerB {
void ping(PlayerA playerA, long ball); //send and forget method call
}
public class PlayerAImpl implements PlayerA {
@Override
@ublic void pong(long ball) {
}
}
public class PlayerBImpl implements PlayerB {
@Override
public void ping(PlayerA playerA, long ball) {
playerA.pong(ball);
}
}
public class PingPongExample {
public void testPingPong() {
// this manager hides the complexity of inter-thread communications
// and it takes control over actor proxies, actor implementations and threads
ActorManager manager = new ActorManager();
// registers actor implementations inside the manager
manager.registerImpl(PlayerAImpl.class);
manager.registerImpl(PlayerBImpl.class);
//Create actor proxies. Proxies convert method calls into internal messages
//which would be sent between threads to a specific actor instance.
PlayerA playerA = manager.createActor(PlayerA.class);
PlayerB playerB = manager.createActor(PlayerB.class);
for(int i = 0; i 《 1000000; i++) {
playerB.ping(playerA, i);
}
}
这两个play能够每秒打500,000个乒乓。但是如果和单个线程执行速度相比,还是很差的,同样代码在单个线程可以到达每秒两百万个。
作者开始研究缓慢的原因,在一些校验和测试以后,他认为是Actors之间发送消息影响了整体性能:
作者找到一个SPSC单生产者和单消费者的无锁队列, public void sendTrain() {
stationIndex.getAndIncrement();
}
}
参考Disruptor,创建线程间传递long值:
public class Train {
//
public static int CAPACITY = 2*1024;
private final long goodsArray; // array to transfer freight goods
private int index;
public Train() {
goodsArray = new long;
}
public int goodsCount() { // returns the count of goods
return index;
}
public void addGoods(long i) { // adds item to the train
goodsArray = i;
}
public long getGoods(int i) { //removes the item from the train
index--;
return goodsArray;
}
}
如下图两个线程传递long:
使用一列火车实现单个生产者单个消费者:
public void testRailWay() {
final Railway railway = new Railway();
final long n = 20000000000l;
//starting a consumer thread
new Thread() {
long lastValue = 0;
@Override
public void run() {
while (lastValue 《 n) {
Train train = railway.waitTrainOnStation(1); //waits for the train at the station #1
int count = train.goodsCount();
for (int i = 0; i 《 count; i++) {
lastValue = train.getGoods(i); // unload goods
}
railway.sendTrain(); //sends the current train to the first station.
}
}
}.start();
final long start = System.nanoTime();
long i = 0;
while (i 《 n) {
Train train = railway.waitTrainOnStation(0); // waits for the train on the station #0
int capacity = train.getCapacity();
for (int j = 0; j 《 capacity; j++) {
train.addGoods((int)i++); // adds goods to the train
}
railway.sendTrain();
if (i % 100000000 == 0) { //measures the performance per each 100M items
final long duration = System.nanoTime() - start;|
final long ops = (i * 1000L * 1000L * 1000L) / duration;
System.out.format(“ops/sec = %,d\n“, ops);
System.out.format(“trains/sec = %,d\n“, ops / Train.CAPACITY);
System.out.format(“latency nanos = %.3f%n\n“,
duration / (float)(i) * (float) Train.CAPACITY);
}
}
}
-线程安全