Звучит так, как будто вы хотите создать единый поток, который обеспечивает весь доступ к базе данных для всей программы, и в этом случае вам не следует передавать данные методу run. Потому что, когда у вас есть один поток, все, что он делает, это вызывает один метод run один раз, когда он запускается, и этот метод run просто продолжает выполняться до тех пор, пока не вернется или поток не будет принудительно завершен. Чтобы сделать это, нужно иметь синхронизированную очередь, скажем, в вашем классе DBAdmin. Затем такие методы, как addCategory, подготовят свои операторы и добавят их в эту общую очередь. Один поток базы данных обрабатывает операторы в очереди по одному, а когда оператор завершается, он уведомляет поток, который добавил его в очередь. Фактически, Java (по крайней мере, в последних версиях) включает в себя набор классов, которые будут делать именно это для вас; они называются исполнителями, и их можно найти в пакете java.util.concurrent. В частности, посмотрите на метод java.util.concurrent.Executors.newSingleThreadExecutor (), который я бы использовал в такой ситуации.
class SQLQueryCallable implements Callable<SQLResultSet> {
private String query;
public SQLQueryCallable(String query) {
this.query = query;
}
public SQLResultSet Call() throws Exception {
// execute query
return results;
}
}
ExecutorService ex = Executors.newSingleThreadExecutor();
// in DBAdmin somewhere:
public SQLResultSet runQuery(String query) {
Future<SQLResultSet> f = ex.submit(new SQLQueryCallable(query));
return f.get(); // this waits for the query to complete
}
Если я неправильно прочитал ваш вопрос, и вы действительно хотите, чтобы каждый запрос к базе данных выполнялся в своем собственном потоке, то я бы предложил создать класс с именем что-то вроде SQLQuery, который реализует Runnable (или расширяет Thread) - фактически, Вы могли бы даже рассмотреть использование java.util.concurrent.Callable, которое позволяет вам возвращать значение из его метода call () (который похож на run ()). Конструктор класса должен принимать оператор SQL в качестве параметра, а его метод run должен выполнять всю работу по выполнению этого оператора. Затем, если вы использовали Callable, вы можете вернуть результат оператора, или, если вы использовали Runnable, вы можете сохранить его в каком-то общедоступном месте. Это простой ответ на вопрос о том, как передавать данные в метод run (): используйте конструктор класса.
class SQLQueryRunnable implements Runnable {
private String query;
public SQLQueryRunnable(String query) {
this.query = query;
}
public void run() {
// execute query
}
}
P.S. Многопоточность - это сложная вещь, к которой нужно привыкнуть, но Java - хороший язык для этого (на мой взгляд).