Привет и счастливое Рождество всем.
У меня проблема с частью моего кода. В моей программе есть поток, который получает вход с клавиатуры и имеет несколько потоков, которые ждут этого ввода.
Сначала пользователи выбирают тот поток, который он собирается отправить этому вводу. Таким образом, мы говорим, что у нас есть 3 потока (0,1,2) плюс поток, который получает ввод на клавиатуре. Сначала пользователь выберет тот поток, с которым он хочет взаимодействовать, и после этого он отправит фактические данные в этот поток.
У меня есть часть кода, которая занимается этим процессом. Для этого я использую'LinkedBlockingQueue '. Поток клавиатуры помещает данные в очередь, а "рабочие" (остальные 3 потока) получают эти данные из этой очереди.
Проблема в том, что все потоки прослушивают ту же самую очередь, поэтому я помещаю идентификатор в эту очередь, чтобы потоки знали, направлены ли данные на них или в другой поток.
Вот код:
Thread Thread_OUT = new Thread(new Runnable() {
@SuppressWarnings("unchecked")
@Override
public void run() {
while(true) {
try {
Object recibido= sharedQueue.take();
sharedQueue.put(recibido);
//System.out.println("Im the thread "+ clientID+" and I got "+recibido.toString());
if(Integer.parseInt(recibido.toString())==clientID){ // If it is for me I get the data
String x = CommandShellServer.data.get(clientID); // just get the data (it is in a hashmap)
CommandShellServer.data.clear(); // empty the hashmap
sharedQueue.clear();
OUT = do_something(x);
}
else{ // If it is not I will forward it to other thread
Thread.currentThread().wait(100);
// sharedQueue.put(recibido);
// sharedQueue.clear();
}
Как вы можете видеть в коде, что я делаю, проверяется, является ли поток, который обрабатывает информацию, тем, который направлен на "Если это так", я обрабатываю его, и если это не так, я помещаю данные снова в очередь, чтобы позволить другие потоки, чтобы проверить его.
Если я выбираю поток 0 для взаимодействия с ним, это работает. Если я выберу другие, это не сделает.
Можете ли вы помочь мне попытаться решить эту ситуацию???
Большое спасибо!
Избавьтесь от общей очереди и пусть каждый поток имеет свои собственные. Затем, когда вы получите ввод, просто отправьте его в очередь соответствующего потока, который предназначен для его получения.
привет, что немного кода я попробовал это
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package Application;
import java.util.ArrayList;
import java.util.Scanner;
/**
*
* @author husseyn
*/
public class producteurConsomateur {
static Scanner clavier;
static ArrayList<String> queu;
public static void main(String[] args) {
queu=new ArrayList<>();
new Thread(){
@Override
public void run() {
clavier=new Scanner(System.in);
while (true) {
try {
sleep(1000);
} catch (Exception e) {
}
System.out.print("tape message :");
String nextLine = clavier.nextLine();
queu.add(nextLine);
// notifyAll();
}
}
}.start();
new Thread(){
@Override
public void run() {
while (true) {
try {
try {
wait();
} catch (Exception e) {
}
synchronized(this){
String get = queu.get(0);
String[] messageFormat = get.split(":");
String id=messageFormat[0];
if (id.toLowerCase().equals("id1")) {
String message=messageFormat[0];
queu.remove(0);
System.out.println("message recived to thread ID1 :"+message);
}}
} catch (Exception e) {
}
}
}
}.start();
new Thread(){
@Override
public void run() {
while (true) {
try {
try {
wait();
} catch (Exception e) {
}
synchronized(this){
String get = queu.get(0);
String[] messageFormat = get.split(":");
String id=messageFormat[0];
if (id.toLowerCase().equals("id3")) {
String message=messageFormat[0];
queu.remove(0);
System.out.println("message recived to thread ID3 :"+message);
}}
} catch (Exception e) {
}
}
}
}.start();
new Thread(){
@Override
public void run() {
while (true) {
try {
try {
wait();
} catch (Exception e) {
}
synchronized(this){
String get = queu.get(0);
String[] messageFormat = get.split(":");
String id=messageFormat[0];
if (id.toLowerCase().equals("id2")) {
String message=messageFormat[0];
queu.remove(0);
System.out.println("message recived to thread ID2 :"+message);
}}
} catch (Exception e) {
}
}
}
}.start();
}
}
и здесь я использую общую очередь, но вы должны уважать формат сообщения, как id1: hello или id2: lol
sharedQueue.put(recibido)
выполнитеqueueMap.get(recibido.toString()).put(recibido)
. А в потоке потребителей удалите проверку для clientID и просто сделайтеmyQueue.take(); String x = CommandShellServer.data.get(clientID); ...