MultiThreading timer efficiency - java

Hello everyone once again i would like to get some suggestions about my code efficiency
Thread thread= new Thread (new Runnable(){
public void run(){
while(true){
PreparedStatement ps = null;
ResultSet rs = null;
try {
Connection con = DatabaseConnection.getConnection();
ps = con.prepareStatement("SELECT Datacolum FROM accounts WHERE id = ? ");
ps.setInt(1, 2);
rs = ps.executeQuery();
if(rs.next()) { //there is a row
LConnection = rs.getInt("Datacolum");
}
ps.close();
} catch (SQLException ex) {}
for (int i = 0; i < 10; i++) { //Timer To Recheck Connection database 10 seconds
try{
Thread.sleep(1000);
}catch(InterruptedException ex){}}
if (LConnection !=1) {
user.Kick(5, "8", 5);
thread.stop();
}}}});
i would really like to know if such Thread will not hurt the rest of the code outside it while this code is looping every 10 seconds, maybe if there is a more efficient Timer Code i would be more then grateful to know. i want this thread to work as long as the user is connected to my application
the code does the next operation starting Looping thread>>it checks a colum>> wait 10 seconds >>enter if operator>>if not met >>Repeat Code
Open for suggestions
Sincerely yours,
Ex

Related

JDBC multiple connections has same performance as single connection

I wrote a simple java program to use JDBC to run 20 queries to fetch data from a view
int connectionSize = 10;
ds.init(connectionSize, settings);
ExecutorService executor = Executors.newFixedThreadPool(10);
try {
stopwatch.start();
for (int i = 0; i < 20; i++) {
executor.execute(new Runnable() {
#Override
public void run() {
String sql = String.format("select * from viewA where userId in (%s)", randomUserIds(5));
PreparedStatement ps = null;
Connection conn = null;
try {
while ((conn = ds.getConnection()) == null) {
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
logger.error(e.getMessage(), e);
}
}
logger.info("conn: " + conn.toString());
ps = conn.prepareStatement(sql);
ps.executeQuery();
ps.close();
} catch (Exception ex) {
ex.printStackTrace();
} finally {
if (conn != null) {
ds.returnConnection(conn);
}
}
}
});
}
executor.shutdown();
boolean finished = executor.awaitTermination(10, TimeUnit.MINUTES);
stopwatch.stop();
logger.log(Level.INFO, "Query Complete in " + stopwatch);
} catch (Exception ex) {
ex.printStackTrace();
}
e.g. select * from ViewA where userId in (random few user Ids)
I used a single connection, and inside a for loop executed the 20 queries in a sequential way
I set up 10 connections in a pool and running the 20 queries in 10 threads
I expected the second approach would use less time to finish the 20 queries, but after testing, the results show me these two approaches return similar time consumption.
I can confirm when I was running the second approach, it created 10 sessions in db.
Is the second approach supposed to give a better performance than the first one? What would be the problem to make the second performance same as the first one?

use java to mock concurrently update count

My colleague told me that in high concurrency mysql could not process update correctly, e.g.
update product set count = count - 1 where id = ? and count > 0;
maybe have count less than 0, I think he is wrong, so I wrote below code to prove this.
int nThreads = 140; //less than max_connections 151
ExecutorService pool = Executors.newFixedThreadPool(nThreads);
CountDownLatch startLatch = new CountDownLatch(nThreads);
CountDownLatch endLatch = new CountDownLatch(nThreads);
for (int i = 0; i < nThreads; i++) {
pool.submit(() -> {
startLatch.countDown();
try { startLatch.await(); } catch (Exception e1) { } //waiting for all task is submitted to guarantee concurrency
String sql = "update t set count = count-1 where id =1 and count>0";
try {
Connection connection = DriverManager.getConnection(url, user, password);
Statement stat = connection.createStatement();
stat.execute(sql);
endLatch.countDown();
} catch (Exception e) {
e.printStackTrace();
}
});
}
endLatch.await(); //waiting for all task is done
System.out.println("done");
System.exit(0);
I'd like to know my above code is could mock high concurrency correctly? and if could simplify above code by java8?
It is not right that mysql can't update data correctly.
MySql lock the record for the update until the transaction is terminated, so no other thread can try to update it if the previous transaction on the same record has not been finished.

how to move from one row to another

I've set my labelTEXT to "T26 content". Then, i want to changet the labelTEXT content to "T30 content" by click "Yes Button" (ps: T26 have T30 IF_YES value). When i click "Yes Button" again, labelTEXT content should change to T25 content. how to do that?
private void btYesActionPerformed(java.awt.event.ActionEvent evt) {
Connection conn = connectionClass.GetConnections();
Statement st;
ResultSet rs;
String task;
task = "T26";
try {
st = conn.createStatement();
rs = st.executeQuery("select * FROM task where ID = '"+task+"'");
while (rs.next()) {
String TEXT = rs.getString("TEXT");
String IF_YES = rs.getString("IF_YES");
labelTEXT.setText(TEXT);
task = IF_YES;
}
} catch (Exception e) {
}
}
hope this clear enough
You would query again for the row corresponding to the new ID based on what the user clicked.
Edit:
Look up prepared statements, as they are a safe way to do things http://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html.
Building from your existing code, it should do something like the following for the queries. The UI and control flow logic will have to be filled in:
private void btYesActionPerformed(java.awt.event.ActionEvent evt) {
Connection conn = connectionClass.GetConnections();
boolean done = false;
PreparedStatement pst;
ResultSet rs;
String task;
task = "T26"; // Set initial value of task
// Assuming one row expected (may want to handle error case later)
query = "SELECT * FROM task WHERE ID = ? LIMIT 1"
try {
pst = conn.prepareStatement(query);
while (!done) {
pst.setString(1, task)
rs = pst.executeQuery()
while (rs.next()) {
String TEXT = rs.getString("TEXT");
String IF_YES = rs.getString("IF_YES");
labelTEXT.setText(TEXT);
task = IF_YES; // Task is now updated for the next loop
}
// TODO: Make sure to set done to false when all tasks complete.
}
pst.close()
conn.close()
} catch (Exception e) {
}
}
Note: you may also want to look into making multiple queries into transactions if needed https://docs.oracle.com/javase/tutorial/jdbc/basics/transactions.html.

Saving to mysql database with jbutton issue

Good day . Can anyone really help me with what i'm facing as issue with my database ? i want to insert to the database by using the pepraredStatement . however whenever i'm adding the database part (connection and pepraredStatement ) the 'UPLOAD' button goes unresponsive . but when i remove anything related to the database , all my buttons are working . you can find here the code http://pastebin.com/euKdWhr2 .
I will really appreciate any help or suggestion . probably i'm missing something on the database part .
And please it is not a duplicated question , because i did not find the right answer
public void actionPerformed(ActionEvent ev)
{
String file = fileField.getText();
SetGetQuestionFileName pattern = new SetGetQuestionFileName(file);
ConnectToDatabase database = new ConnectToDatabase();
try
{
///////// check whether textfile is empty or not
if( ev.getActionCommand().equals("UPLOAD"))
{
if(fileField.getText().isEmpty())
{
JOptionPane.showMessageDialog(null,"File field can not be empty!!! Please try again.","ALERT", JOptionPane.ERROR_MESSAGE);
}
else
{
File fi = new File(fileField.getText());
//////////////// perform upload
try
{
String sql = "INSERT INTO testsystem.questionnaire (category_questions, questions, correct_answer)" + "VALUES (?, ?, ?)";
PreparedStatement st = null;
Connection dbconnection = database.getConnection();
st = dbconnection.prepareStatement(sql);
if(fi.getAbsoluteFile().exists())
{
List<String> lines = Files.readAllLines(Paths.get(fileField.getText()), Charset.defaultCharset());
for (int i = 0; i < lines.size(); i+=10)
{
String category = lines.get(i);
System.out.println(category);
String question = lines.get(i+1);
System.out.println(question);
String answers =
lines.get(i+2)+System.lineSeparator()
+lines.get(i+3)+System.lineSeparator()
+lines.get(i+4)+System.lineSeparator()
+lines.get(i+5);
System.out.println(answers);
String correct = lines.get(i+7);
System.out.println("correct answer is: "+correct);
System.out.println("----------------");
st.setString(1, category);
st.setString(2, answers);
st.setString(3, correct);
st.executeUpdate();
}
JOptionPane.showMessageDialog(null,"File has been successfully uploaded in the database.","NOTIFCATION",JOptionPane.INFORMATION_MESSAGE);
}
else
JOptionPane.showMessageDialog(null,"File could not be found. Please try again","ALERT",JOptionPane.ERROR_MESSAGE);
}
catch(SQLException ex)
{
}
catch(Exception ex)
{
}
Swing is a single threaded framework. Any operation which is long running or blocking, when executed within the context of the Swing's GUI thread (the Event Dispatching Thread) will prevent it from updating the screen.
Take a look at Concurrency in Swing and Worker Threads and SwingWorker for more details

Limitations of MySQL JDBC

Problem:
I get large ResultSet from DB(MySQL)(more than 1 000 000 rows) and handle each row about 40 seconds.
Summary, i work with ResultSet more than 30 minutes, i get less records than really contain in database table аnd have no errors and no warrnings. If i count quantity of rows of that ResultSet, it's allright(quantity of ResultSet = quantity of DB).
Is some limitations of mysql server or mysql jdbc driver or something else?
My code. it works in spring framework :
public void query(String query, RowCallbackHandler rowCallbackHandler) throws SQLException {
ResultSet rs = null;
ResultSet rsCount = null;
Statement stmt = null;
Statement stmtCount = null;
try {
stmt = createStatmant();
rs = stmt.executeQuery(query);
if (rs == null) {
log.info("result set is null");
}
stmtCount = createStatmant();
rsCount = stmtCount.executeQuery(query);
int i = 0;
while(rsCount.next()){
i++;
}
log.info("ResultSet size : "+i);
int j = 0;
rs.next();
do{
j++;
rowCallbackHandler.processRow(rs);
}while (rs.next());
log.info("ResultSet size real : "+i);
log.info("ResultSet size fact : "+j);
} catch (SQLException e) {
throw new RuntimeException(e.getMessage());
}finally{
if(stmt!=null){
stmt.close();
}
if(rs!=null){
rs.close();
}
if(rsCount!=null){
rsCount.close();
}
}
}
createStatment :
private Statement createStatmant() throws SQLException {
((BasicDataSource)dataSource).setTimeBetweenEvictionRunsMillis(1000*60*60);
Statement stmt = dataSource.getConnection().createStatement(
ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
stmt.setFetchSize(fetchSize);
stmt.setMaxRows(50000000-1);
return stmt;
}
datasource is global variable in class:
private javax.sql.DataSource dataSource;
You're handing a mutable object, rs, back to your callbackHandler. Make sure it's not advancing or closing the ResultSet.
You declare four objects that can be closed at the top of your method, but only close three at the bottom. Don't forget to close stmtCount.
I'm assuming you're performing that count as a troubleshooting approach for our benefit, and that you're not doing that in production.
1 Million rows times 40 Seconds = 40 Million Seconds = 463 days. The math doesn't support the statement that you "handle each row about 40 seconds".
Is anything externally writing to the database as you're reading?
If you're able to compare counts from your log, it means you haven't thrown an Exception. That's a useful clue.

Categories