2010-06-24 1 views
1

Я создал один поток с параметрами java.sql.Connection и String. Но изнутри потока я заметил, что значение String доступно, но объект Connection не был. Любые подсказки?java.sql.Connection не видно изнутри потока

(Редактирование детали в вопросе):

Ну, кажется, что объект подключения доступен, но закрыт внутри нити. Вот код:

package com.catgen.helper; 

import java.sql.Connection; 

public class ImageCheckHelper extends Thread{ 

    public Connection conn = null; 
    public String str = null; 

    public ImageCheckHelper(Connection conn, String str){ 
     this.conn = conn; 
     this.str = str; 
     try{ 
      System.out.println("From inside the constructor"); 
      System.out.println((this.conn!=null)?"Connection is not null":"Connection is null"); 
      System.out.println((this.str!=null)?"String is not null":"String is null"); 
      System.out.println((this.conn.isClosed())?"Connection is closed.":"Connection is not closed"); 
      System.out.println("\n\n"); 
     }catch(Exception e){ 
      e.printStackTrace(); 
     } 
    } 

    public void run(){ 
     try{ 
      System.out.println("From inside the thread"); 
      System.out.println((conn!=null)?"Connection is not null":"Connection is null"); 
      System.out.println((str!=null)?"String is not null":"String is null"); 
      System.out.println((conn.isClosed())?"Connection is closed.":"Connection is not closed"); 
     }catch(Exception e){ 
      e.printStackTrace(); 
     } 
    } 

    public void initiateImageCheck(){ 
     this.start(); 
     return; 
    } 
} 

И вот результат:

From inside the constructor 
Connection is not null 
String is not null 
Connection is not closed 



From inside the thread 
Connection is not null 
String is not null 
Connection is closed. 
+3

Не без вас какой-либо код, нет ... –

+0

Остерегайтесь того, что объекты JDBC, такие как 'Connection',' Statement', 'ResultSet' и т. Д., Вообще не являются потокобезопасными; не используйте эти объекты из нескольких потоков одновременно. Если у вас есть несколько потоков, обращающихся к одной и той же базе данных одновременно, каждому потоку потребуется отдельное соединение. – Jesper

+0

Большое спасибо Jesper. – James

ответ

0

Я не вижу, что ваша проблема - смотрит на выходе, вы можете увидеть, что оба Connection и String не являются -находится в конструкторе и, когда вы приходите, чтобы запустить поток.

Единственная разница в том, что соединение было закрыто в какой-то точке между создаваемой нитью и выполняемой нитью. В зависимости от того, как вы предоставили соединение и как другие потоки использовали его, это не особенно необычно. В любом случае вы должны смотреть на другие потоки, вызывающие close() на том же объекте Connection, если вы хотите отслеживать это.

Как правило, проще всего, чтобы каждая нить управляла своим собственным соединением, потому что в противном случае вы получите очень сложную семантику относительно фиксации и закрытия (как вы видели здесь). Совместное использование соединения между несколькими потоками может работать, и в редких случаях это необходимо, но в целом это скорее исключение, чем правило.

Редактирование: Кроме того, много реализаций Connection даже не являются потокобезопасными, поэтому вы не можете реально использовать их между несколькими потоками надежным способом. Если один поток запускает инструкцию, а затем попытается использовать соединение в другом потоке, то произойдет плохие вещи. Еще больше оправданий, чтобы просто дать каждой теме свою собственную связь и позволить ей продолжить то, что она хочет сделать, без необходимости участвовать в какой-то синхронизации мьютексов (узкое место, которое также устраняет некоторые привлекательности многопоточности!).

+0

Любая идея, как соединение может быть доступно (не закрыто) внутри потока? – James

+0

James - единственный способ сделать это, чтобы ** не закрыть соединение в другом месте **. Но, как я сказал, лучшим решением в целом является обеспечение того, чтобы каждый поток использовал свое собственное соединение. –

+0

Как вы можете видеть из кода, соединение не закрывается явно нигде. Кажется, это происходит неявно. Мое требование здесь состоит в том, чтобы создать только один поток и передать соединение для дальнейшего использования. Использование потока заключается в том, чтобы сообщить пользователю, что процесс был инициирован сразу после начала действия, без необходимости ждать, пока пользователь выполнит действие. – James

0

Является ли другой поток закрывающим соединение между временем, заданным им конструктором, и временем, которое оно используется в методе run()? Я предполагаю, что соединение закрыто после вызова initiateImageCheck(), но до того, как метод run() достигнет отметки isClosed().

Если нет, есть ли у вас доступ к исходному коду драйвера JDBC? Интересно, защищает ли он себя от многопоточного использования.

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

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

+0

У вас есть полный код перед вами. Соединение не закрывается где-либо еще. О несинхронизированном доступе я сделал это, чтобы упростить код здесь, так как у нас есть только один поток. – James

+0

Ну, сразу же после создания потока нормальный поток, используемый для продолжения, и завершите соединение в конце. Спасибо большое richj. – James

Смежные вопросы