Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将带有Executor服务的Java多线程迁移到Akka_Java_Multithreading_Akka - Fatal编程技术网

将带有Executor服务的Java多线程迁移到Akka

将带有Executor服务的Java多线程迁移到Akka,java,multithreading,akka,Java,Multithreading,Akka,我只是想知道是否有可能将用Java的Executor服务编写的旧多线程代码替换为Akka。对此我没有什么疑问 Is akka actor runs in their own thread? How Threads will be assigned for the Actors ? What are the pros and cons of migration of it is possible? 目前我使用固定线程池进行多线程,并提交一个可调用的线程池 示例代码 public class

我只是想知道是否有可能将用Java的Executor服务编写的旧多线程代码替换为Akka。对此我没有什么疑问

Is akka actor runs in their own thread? 

How Threads will be assigned for the Actors ?

What are the pros and cons of migration of it is possible?
目前我使用固定线程池进行多线程,并提交一个可调用的线程池

示例代码

public class KafkaConsumerFactory {

    private static Map<String,KafkaConsumer> registry = new HashMap<>();

    private static ThreadLocal<KafkaConsumer> consumers = new ThreadLocal<KafkaConsumer>(){
        @Override
        protected KafkaConsumer initialValue() {
            return new KafkaConsumer(createConsumerConfig());
        }
    };

    static {
        Runtime.getRuntime().addShutdownHook(new Thread(){
            @Override
            public void run() {
                registry.forEach((tid,con) -> {
                    try{
                        con.close();
                    } finally {
                        System.out.println("Yes!! Consumer for " + tid + " is closed.");
                    }
                });
            }
        });
    }

    private static Properties createConsumerConfig() {
        Properties props = new Properties();
        props.put("bootstrap.servers", "localhost:9092");
        props.put("group.id", "newcon-grp5");
        props.put("key.deserializer", StringDeserializer.class.getName());
        props.put("value.deserializer", KafkaKryoSerde.class.getName());
        return props;
    }


    public static <K,V> KafkaConsumer<K,V> createConsumer(){
        registry.put(Thread.currentThread().getName(),consumers.get());
        return consumers.get();
    }
}
公共级卡夫卡消费工厂{
私有静态映射注册表=new HashMap();
私有静态ThreadLocal使用者=新ThreadLocal(){
@凌驾
受保护的Kafka消费者初始值(){
返回新的KafkaConsumer(createConsumerConfig());
}
};
静止的{
Runtime.getRuntime().addShutdownHook(新线程(){
@凌驾
公开募捐{
registry.forEach((tid,con)->{
试一试{
con.close();
}最后{
System.out.println(“是!!“+tid+”的消费者关闭”);
}
});
}
});
}
私有静态属性createConsumerConfig(){
Properties props=新属性();
put(“bootstrap.servers”,“localhost:9092”);
道具出售(“group.id”、“newcon-grp5”);
put(“key.deserializer”,StringDeserializer.class.getName());
put(“value.deserializer”,KafkaKryoSerde.class.getName());
返回道具;
}
公共静态KafkanConsumer createConsumer(){
registry.put(Thread.currentThread().getName(),consumers.get());
返回消费者。get();
}
}
/////////////////////////////////////////////////////////

import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.ConsumerRecords;
import org.apache.kafka.clients.consumer.KafkaConsumer;
import org.apache.kafka.common.TopicPartition;
import org.apache.kafka.common.serialization.StringDeserializer;

import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;

public class KafkaNewConsumer {
    public static int MAX_THREADS = 10;
    private ExecutorService es = null;
    private boolean stopRequest = false;




    public static void main(String[] args){
        KafkaNewConsumer knc = new KafkaNewConsumer();
        Runtime.getRuntime().addShutdownHook(new Thread(){
            @Override
            public void run(){
                knc.es.shutdown();
                try {
                    knc.es.awaitTermination(500, TimeUnit.MILLISECONDS);
                } catch (InterruptedException ignored) {

                }finally {
                    System.out.println("Finished");
                }
            }
        });

        knc.consumeTopic("rtest3",knc::recordConsuemer);

    }

    public void recordConsuemer(ConsumerRecord<?,?> record){
        String result = new StringJoiner(": ")
                .add(Thread.currentThread().getName())
                .add("ts").add(String.valueOf(record.timestamp()))
                .add("offset").add(String.valueOf(record.offset()))
                .add("data").add(String.valueOf(record.value()))
                .add("value-len").add(String.valueOf(record.serializedValueSize()))
                .toString();
        System.out.println(result);
    }
    public void  consumeTopic(String topicName, Consumer<ConsumerRecord<?,?>> fun){
        KafkaConsumer con= KafkaConsumerFactory.createConsumer();
        int paritions = con.partitionsFor(topicName).size();
        int noOfThread = (MAX_THREADS < paritions) ? MAX_THREADS :paritions;
         es = Executors.newFixedThreadPool(noOfThread);
        con.close();
        for(int i=0;i<noOfThread;i++){
            es.submit(()->{
                KafkaConsumer consumer = KafkaConsumerFactory.createConsumer();
                try{
                    while (!stopRequest){
                        consumer.subscribe(Collections.singletonList(topicName));
                        ConsumerRecords<?,?> records = consumer.poll(5000);

                        records.forEach(fun);
                        consumer.commitSync();
                    }
                }catch(Exception e){
                    e.printStackTrace();
                } finally {
                    consumer.close();
                }
            });
        }
    }
}
import org.apache.kafka.clients.consumer.ConsumerRecord;
导入org.apache.kafka.clients.consumer.ConsumerRecords;
导入org.apache.kafka.clients.consumer.KafkaConsumer;
导入org.apache.kafka.common.TopicPartition;
导入org.apache.kafka.common.serialization.StringDeserializer;
导入java.util.*;
导入java.util.concurrent.ExecutorService;
导入java.util.concurrent.Executors;
导入java.util.concurrent.TimeUnit;
导入java.util.function.Consumer;
公共类KafkaNewConsumer{
公共静态int MAX_线程=10;
私有执行者服务=null;
私有布尔stopRequest=false;
公共静态void main(字符串[]args){
KafkaNewConsumer knc=新的KafkaNewConsumer();
Runtime.getRuntime().addShutdownHook(新线程(){
@凌驾
公开募捐{
knc.es.shutdown();
试一试{
knc.es.等待终止(500,时间单位毫秒);
}捕获(InterruptedException被忽略){
}最后{
系统输出打印项次(“完成”);
}
}
});
consumertopic(“rtest3”,knc::recordConsuemer);
}
公共作废记录消费者(消费者记录记录){
字符串结果=新的StringJoiner(“:”)
.add(Thread.currentThread().getName())
.add(“ts”).add(String.valueOf(record.timestamp()))
.add(“偏移量”).add(String.valueOf(record.offset()))
.add(“数据”).add(String.valueOf(record.value()))
.add(“value len”).add(String.valueOf(record.serializedValueSize()))
.toString();
系统输出打印项次(结果);
}
public void consumertopic(字符串topicName,Consumer records=Consumer.poll(5000);
记录。forEach(乐趣);
consumer.commitSync();
}
}捕获(例外e){
e、 printStackTrace();
}最后{
consumer.close();
}
});
}
}
}
我浏览了一些网络教程,其中一些直接得出结论

演员非常优秀,比传统的线程速度更快

但没有解释它如何比线程更快?

我尝试了一些示例Akka(来自activator的Akka示例)代码,并在所有参与者中打印了Thread.currentThread.getName,发现创建了名为(helloakka-Akka.actor.default-dispatcher-X)的不同调度程序线程

但是怎么做呢?谁在创建这些线程?它们的配置在哪里?线程和参与者之间的映射关系是什么?


每次我发送消息时,Akka会创建新线程吗?或者在内部使用线程池?

若我需要100个线程来并行执行某个任务的某些部分,我是否需要创建100个参与者并向每个参与者发送一条消息?或者我需要创建一个actor并将100条消息放入它的队列中,它将被分成100个线程。


真正令人困惑的

迁移到actor系统对于基于executor的系统来说不是一项小任务,但它是可以完成的。它要求你重新思考你设计系统的方式,考虑演员的影响。例如,在线程体系结构中,您为业务流程创建一些处理程序,将其放入可运行状态,让它在线程上执行操作。这对于一个演员范例来说是完全不合适的。您必须重新设计您的系统,以处理消息传递和使用消息来调用任务。此外,您还必须改变对业务流程的思考方式,从命令式方法转变为基于消息的方法。举例来说,考虑购买产品的简单任务。我假设你知道如何在遗嘱执行人身上做这件事。在actor系统中,您可以执行以下操作:

(采购产品)->UserActor->(BillCredit Card)->CCProcessing Actor->(采购批准并计费的项目)->库存经理->。。。等等

在每个阶段,括号中是发送给相关参与者的异步消息,该参与者执行业务逻辑,然后将消息转发给流程中的下一个参与者

现在这只是一个开始