Передача переменных между потоками ExecutorService

231
13 мая 2018, 18:10

Создал бота Discord, с возможностью подключения к нему по сокетам. Код для создания самого бота

    package ru.frostdelta.botClient;
import sx.blah.discord.api.ClientBuilder;
import sx.blah.discord.api.IDiscordClient;
import sx.blah.discord.api.events.EventDispatcher;
import sx.blah.discord.api.events.IListener;
import sx.blah.discord.handle.impl.events.guild.channel.message.MessageReceivedEvent;
import sx.blah.discord.handle.obj.IChannel;
import sx.blah.discord.handle.obj.IMessage;
import sx.blah.discord.util.DiscordException;
import sx.blah.discord.util.MessageBuilder;
import sx.blah.discord.util.MissingPermissionsException;
import sx.blah.discord.util.RateLimitException;
import java.net.Socket;
import java.util.concurrent.Exchanger;
public class EchoBot implements Runnable, IListener<MessageReceivedEvent> {
    public String clientCommand = null;
    public static final String ECHO_BOT_TOKEN = "";
    private IDiscordClient dscordClient;
    private boolean isConnected;
    Exchanger<String> exchanger;
    String message;
    MultiThreadServer mts = new MultiThreadServer();
    public EchoBot(){
        this.isConnected = false;
    }
    private void regBot(){
        EventDispatcher dispatcher = dscordClient.getDispatcher();
        dispatcher.registerListener(this);
    }
    public void login() throws DiscordException{
        ClientBuilder cBuilder = new ClientBuilder();
        cBuilder.withToken(EchoBot.ECHO_BOT_TOKEN);
        dscordClient = cBuilder.login();
        regBot();
        this.isConnected = true;
    }

    public void run(){
        try{
            exchanger.exchange(message);
            System.out.println("PutThread has received: " + message);
        }
        catch(InterruptedException ex){
            System.out.println(ex.getMessage());
        }
    }

    public void handle(MessageReceivedEvent event) {

        IMessage content = event.getMessage();
        IChannel channel = content.getChannel();
        message = content.getContent();
        try {
            exchanger.exchange(message);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        try{
            new MessageBuilder(this.dscordClient).withChannel(channel).withContent(clientCommand).build();
        }
        catch(RateLimitException e){
            System.err.println("Ошибка при отправке сообщения: " + e.getMessage());
            e.printStackTrace();
        }
        catch(DiscordException e){
            System.err.println("Ошибка при отправке сообщения: " + e.getMessage());
            e.printStackTrace();
        }
        catch(MissingPermissionsException e){
            System.err.println("Ошибка при отправке сообщения: " + e.getMessage());
            e.printStackTrace();
        }
    }
    static void runAsynchronouslyConnect(final MultiThreadServer obj) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    obj.createServer();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
    public static void main(String[] args){
        MultiThreadServer mts = new MultiThreadServer();
        EchoBot echoDiscordBot = new EchoBot();
        runAsynchronouslyConnect(mts);
        try{
            echoDiscordBot.login();
            System.out.println("Бот успешно подключен.");
        }
        catch(DiscordException e){
            System.err.println("Ошибка при подключении бота к Discord: " + e.getMessage());
        }
    }
}

Итак, бот должен передать переменную в один из потоков, с которыми работают следующие классы. Первый - класс, принимающий подключения и направляющий их в отдельный диалог. Таким образом получается пул потоков.

  package ru.frostdelta.botClient;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.Exchanger;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class MultiThreadServer {
    static ExecutorService executeIt = Executors.newFixedThreadPool(2);
    public static void createServer() {
        Exchanger<String> ex = new Exchanger<String>();
        try (ServerSocket server = new ServerSocket(3345);
             BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) {
             System.out.println("Server socket created, command console reader for listen to server commands");

            while (!server.isClosed()) {
                Socket client = server.accept();
                executeIt.execute(new MonoThreadClientHandler(client));
                System.out.print("Connection accepted.");
            }
            executeIt.shutdown();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Класс, отвечающий за диалог с клиентом

  package ru.frostdelta.botClient;
import java.io.*;
import java.net.Socket;
import java.util.HashMap;
import java.util.concurrent.Exchanger;
public class MonoThreadClientHandler implements Runnable{
    private static Socket clientDialog;
    public MonoThreadClientHandler(Socket client) {
        MonoThreadClientHandler.clientDialog = client;
    }

    EchoBot eb = new EchoBot();
    Exchanger<String> exchanger;
    String message;
    public void run() {
        String password = "123456";
        HashMap<Boolean, String> auth = new HashMap<Boolean, String>();
        auth.put(true, password);
        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            DataOutputStream out = new DataOutputStream(clientDialog.getOutputStream());
            DataInputStream in = new DataInputStream(clientDialog.getInputStream());
            System.out.println("DataInputStream created");
            System.out.println("DataOutputStream  created");
            if(auth.get(true).equalsIgnoreCase(in.readUTF())) {
                out.writeUTF("Connection accepted!");
                out.flush();
                System.out.println("Server ready to send commands");
                while (!clientDialog.isClosed()) {
                    String command = eb.clientCommand;
                    System.out.println(command);
                    if (command != null) {
                            out.writeUTF(command);
                            out.flush();
                            System.out.println("Command " + command + " send!");
                            eb.clientCommand = null;
                    }
                }
                System.out.println("Client disconnected");
                System.out.println("Closing connections & channels.");
                in.close();
                out.close();
                clientDialog.close();
                System.out.println("Closing connections & channels - DONE.");
            }else{
                out.writeUTF("Password incorrect!");
                out.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Однако, последний класс выдаёт мне, что переменная command == null http://prntscr.com/jgl082 даже после того как я напишу сообщение и бот точно примет его. http://prntscr.com/jgkzce Вопрос. Как передать переменную между потоками в данном случае?

READ ALSO
Как вставить фрагмент jsf страницы в &lt;IFrame/&gt;?

Как вставить фрагмент jsf страницы в <IFrame/>?

Решаемая задача, есть legacy с бэкэндом на jsfМне нужно перейти на Spring + reactJS

193
Изображения в мобильной версии bootstrap 4

Изображения в мобильной версии bootstrap 4

Лендинг http://adrenalin-ufaru , в секции carousel , в мобильной версии неправильно отображаются изображения ( отображается левая часть , а необходимо , что...

138
Какие стили нужно задать, что бы получилась равнозначная сетка из блоков?

Какие стили нужно задать, что бы получилась равнозначная сетка из блоков?

Есть перечень услуг, которые идут ровно по горизонтали, но беспорядочно по вертикалиКак правильно оформить, чтобы вертикаль тоже была симметрична?...

201
Как сделать hover effect с иконкой поверх картинки?

Как сделать hover effect с иконкой поверх картинки?

Мне необходимо с помощью css и его :hover наложить градиент и icon поверх картинкиВыглядеть это должно примерно вот так, у меня же получается это...

260