0

I am facing problem. We are writting Java application as school project and we are supposed to use threads. Obviously, the application is not as complex to require threads, but we have to have them.

We decided to use threads for database communication, but we are not sure, how to use them for single methods. We created Database Transfer Object with some methods to insert entities into DB. How to use Runnable for single methods, please? To be more specific, we would like to create Runnable in methods and then add it to thread pool, but then, we would be able to get returns back.

public class EmployeeDTO {

    private Employee employee;
    private Connection conn;
    private int id_employee;

    /**
     * Database connection
     * @throws ClassNotFoundException
     * @throws SQLException 
     */
    public EmployeeDTO() throws ClassNotFoundException, SQLException {
        DatabaseConnection dbcon = new DatabaseConnection();
        conn = dbcon.getConnection();
    }

    public EmployeeDTO(Employee employee) throws ClassNotFoundException, SQLException {
        this.employee = employee;
        DatabaseConnection dbcon = new DatabaseConnection();
        conn = dbcon.getConnection();
    }

    /**
     * Insert new Employee into database and sets it's id
     * @param emp
     * @throws SQLException 
     */
    public void insertEmployee(Employee emp) throws SQLException {
        setEmployee(emp);
        PreparedStatement pr = conn.prepareStatement("INSERT INTO employees "
                + "(nickname,name,surname,password_emp) "
                + "VALUES (?,?,?,?)", PreparedStatement.RETURN_GENERATED_KEYS);
        pr.setString(1, employee.getNickname());
        pr.setString(2, employee.getName());
        pr.setString(3, employee.getSurname());
        pr.setString(4, employee.getPassword());
        pr.executeUpdate();
        ResultSet rs = pr.getGeneratedKeys();
        while (rs.next()) {
            employee.setId_employee(rs.getInt(1));
        }
    }

    /**
     * Delete an employee from database
     * @param id
     * @throws SQLException 
     */
    public void deleteEmployee(int id) throws SQLException {
        PreparedStatement pr = conn.prepareStatement("DELETE FROM employees WHERE id_employee=?");
        pr.setInt(1, id);
        pr.executeUpdate();
    }
}
spiderman
  • 289
  • 3
  • 15
Jakub Gruber
  • 745
  • 1
  • 11
  • 27
  • Have a look at : http://stackoverflow.com/questions/141284/the-difference-between-the-runnable-and-callable-interfaces-in-java/35407598#35407598 – Ravindra babu May 19 '16 at 20:08

2 Answers2

0

To be more specific, we would like to create Runnable in methods and then add it to thread pool, but then, we would be able to get returns back.

Sounds like you want to submit Callable tasks (not Runnable) to a thread pool. When you submit a Callable<T> task to an ExecutorService, you get back a Future<T> object that you can use at a later time to wait for the result of the task.

Solomon Slow
  • 25,130
  • 5
  • 37
  • 57
  • Thank you for your answer. So if we would create an instance of Callable object in methods' body, then implemented call method, inserted our code into call method implementation and finally added this Callable object to some ArrayList (Queque) in ThreadPool, would it be right solution? – Jakub Gruber May 19 '16 at 19:42
  • I don't have time to explain it, but there's plenty of good explanations already out there. Google for 'java ExecutorService tutorial'. – Solomon Slow May 19 '16 at 19:54
0

You may want to do something like below. Your insertEmployee method will be called from call method.

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.concurrent.Callable;

public class EmployeeDTO implements Callable<String> {

    private Employee employee;
    private Connection conn;
    private int id_employee;

    /**
     * Database connection
     * @throws ClassNotFoundException
     * @throws SQLException
     */
    public EmployeeDTO() throws ClassNotFoundException, SQLException {
        DatabaseConnection dbcon = new DatabaseConnection();
        conn = dbcon.getConnection();
    }

    public EmployeeDTO(Employee employee) throws ClassNotFoundException, SQLException {
        this.employee = employee;
        DatabaseConnection dbcon = new DatabaseConnection();
        conn = dbcon.getConnection();
    }

    /**
     * Insert new Employee into database and sets it's id
     * @param emp
     * @throws SQLException
     */
    public void insertEmployee(Employee emp) throws SQLException {
        setEmployee(emp);
        PreparedStatement pr = conn.prepareStatement("INSERT INTO employees "
                + "(nickname,name,surname,password_emp) "
                + "VALUES (?,?,?,?)", PreparedStatement.RETURN_GENERATED_KEYS);
        pr.setString(1, employee.getNickname());
        pr.setString(2, employee.getName());
        pr.setString(3, employee.getSurname());
        pr.setString(4, employee.getPassword());
        pr.executeUpdate();
        ResultSet rs = pr.getGeneratedKeys();
        while (rs.next()) {
            employee.setId_employee(rs.getInt(1));
        }
    }

    /**
     * Delete an employee from database
     * @param id
     * @throws SQLException
     */
    public void deleteEmployee(int id) throws SQLException {
        PreparedStatement pr = conn.prepareStatement("DELETE FROM employees WHERE id_employee=?");
        pr.setInt(1, id);
        pr.executeUpdate();
    }

    /**
     * Computes a result, or throws an exception if unable to do so.
     *
     * @return computed result
     * @throws Exception if unable to compute a result
     */
    public String call() throws Exception {
        insertEmployee(employee);
        return "SUCCESS";
    }
}

In other class you can use the ExecutorService like below

try{
Set<Callable<String>> callables = new HashSet<Callable<String>>();
EmployeeDTO  employee = new EmployeeDTO(emp);
  callables.add(employee); 
ExecutorService  executorService =  Executors.newFixedThreadPool(1);
List<Future<String>> futures = executorService.invokeAll(callables);
}catch (ExecutionException eEx) {
eEx.getMessage();
}finally{
executorService.shutdown();
}
Vijendra Kumar Kulhade
  • 2,217
  • 3
  • 15
  • 25
  • Thank you, it will definitely help me a lot. But is there a way, to have call method for every method in DTO? I would like to have single thread for one entity/class – Jakub Gruber May 20 '16 at 06:16
  • I don't think you may want to do like that. As it will create the amibiguous behavior if multiple thread works on EmployeeDTO. You can put some logic where you can tell your thread to do the specific operation like insert or delete may be some flag. Please accept the answer if it answered your question. – Vijendra Kumar Kulhade May 20 '16 at 06:36