I want to insert data with using JDBC.
I write this code :
//I want to start threads here
while(stmt_ver.next()){
stmt_ver.setString(i, "test"+... );
stmt_ver.executeBatch();
connection_ver.commit();
}
//I want to finish threads here
How can I do this with thread?
Here you go. Updated answer with code
Threaded class
public class MyThreadedClass extends Thread{
//Do what I need here on a thread
public void run(){
//Do what I need here
}
}
Main
//Main class
public static class MyProgramMain{
//Program main
public static void main(String[] args) {
//Send 10 threads
for (int i=0; i<10; i++){
//Init class (threaded)
MyThreadedClass threadedClass = new MyThreadedClass();
//Execute code in the class run() method
threadedClass.start();
}
}
}
Your question is hard to answer. You are asking very vague. Try to be clear. Post all necessary code. Try to explain what you did and what you would like to do.
Here is some hint for you. It will not run if you copy and past it, but I think it should make clear what you can try:
int i = 0;
while(i < columnCount ){
// make a new statement
Statement stmt_ver = new Statement();
// set your data and make the statement ready
stmt_ver.set...
// make a new thread that executes your data
// and let it run
new Thread(){
public void run(){
stmt_ver.addBatch();
stmt_ver.executeBatch();
connection_ver.commit();
}
}.start();
i++;
}
This is a very simple solution. It will start a thread it each iteration. Since I/O typically is taking some time, this could improve the execution time of your code. But be aware - threading is not easy. This is a very simple, naive solution. It could cause more problems than it solves. If you are not familiar with threads (and it seems like you are not) don't do it!
new Thread(new Runnable(){
#Override public void run(){
//enter code here
}
}).start();
EDIT You want to insert with many threads in parallel ...
There are many different possibilities.
You should read about: Concurrency (concurrent collections) and Executors.
EDIT 2 I agree with Thomas Uhrig , that introducing Threads could be more a harm than a blessing here.
Why do you think it would be helpful?
public class MockCommonDao {
ArrayList<ArrayList> listOlists = new ArrayList<ArrayList>();
public List CommonInsert(List<Object> example)
{
List<Future<Object>> listOlists = null;
ExecutorService executor = Executors.newFixedThreadPool(example.size());
List<TransactionImpl> callingList = new ArrayList<MockCommonDao.TransactionImpl>();
for (int i = 0; i < example.size(); i++) {
TransactionImpl localImpl = new TransactionImpl(example.get(i));
callingList.add(localImpl);
}
try {
listOlists = executor.invokeAll(callingList);
} catch (InterruptedException e) {
}
return listOlists;
}
private class TransactionImpl implements Callable<Object>{
private Object example;
TransactionImpl(Object Criteria) {
this.example = Criteria;
}
#Override
public Object call() throws Exception {
private class TransactionImpl implements Callable<Object>{
private Object example;
TransactionImpl(Object Criteria) {
this.example = Criteria;
}
#Override
public Object call() throws Exception {
while(stmt_ver.next()){
stmt_ver.setString(i, "test"+... );
stmt_ver.executeBatch();
connection_ver.commit();
}
}
}}
}
This code will make simualtaneous insert depending on value of your threads you want to create for insert.example.size() determines number of insert operations you want to perform.Hope you mean this.
Related
I have an array of int with size 4, only one thread can access an array cell at a time.
I thought about using Semaphore but I don't know how or if there is a way to get the acquired index
I build a code example to explain butter:
public class Temp {
private ExecutorService executeService;
private Semaphore semaphore;
private int[] syncArray; // only one thread can access an array cell at the same time
public Temp() {
syncArray = new int[]{1,2,3,4};
executeService = Executors.newFixedThreadPool(10);
semaphore = new Semaphore(syncArray.length, true);
for(int i = 0;i < 100; i++) {
executeService.submit(new Runnable() {
#Override
public void run() {
semaphore.acquire();
// here I want to access one of the array cell
// dose not matter witch one as long as no other thread is currently use it
int syncArrayIndex = semaphore.getAcquiredIndex(); // is something like this possible?
syncArray[syncArrayIndex] += ...;
semaphore.release();
}
});
}
}
}
Edit:
this is a piece of code that looks closer the my real problem:
public class Temp {
private ExecutorService executeService;
private Semaphore semaphore;
private static ChromeDriver driver;
public Temp() {
executeService = Executors.newFixedThreadPool(10);
}
public Future<WikiPage> getWikiPage(String url) {
executeService.submit(new PageRequest(url) {
});
}
private static class PageRequest implements Callable<WikiPage> {
String url;
public PageRequest(String url) {
this.url = url;
}
#Override
public WikiPage call() throws Exception {
String html = "";
synchronized (driver) {
html = ...// get the wiki page, this part takes a log time
};
WikiPage ret = ...// parse the data to the WikiPage class
// this part takes less time but depend on the sync block above
return ret;
}
}
}
#Kayaman I'm not sure I understand your comment, the problem is that I return a future. Do you have a any suggestions on how to improve my code to run faster?
No, semaphore isn't useful here. It only knows about how many permits it has, there are no "indices" in a semaphore.
You can use AtomicIntegerArray instead, although if you explain your root problem, there may be a more suitable class to use.
If multiple threads are triggered does String variable (status) need to be synchronized?
class Request{
String status;
....// Some other variables used in thread
}
class Test{
public static void main(String[] args){
Requesr r = new Request();
List<Future> list= new ArrayList<Future>();
ExecutorService pool= Executors.newFixedThreadPool(10);
for(String input : inputList){
if(!"failed."equals(r.status)){
RequestHandler request = new RequestHandler(input,r);
Future f = pool.submit(request);
list.add(f);
}else{
//fail the job and return;
}
}
for (Future fTemp : list) {
if (fTemp.get() == null) {
// Task completed
}
}
}
}
class RequestHandler extends Runnable{
Map<String,String> input;
Requesr r;
RequestHandler(Map<String,String> input, Request r ){
this.input=input;
this.r = r;
}
#Override
public void run() {
if(!"failed".equals(r.status)){
try{
//some logic
}catch(Exception e){
r.Status = "failed";//status is assigned a value only here
}
}
}
}
Does status need to be synchronized for it to be visible in the Test class for loop and in other threads?
As mentioned below in comments I will use Future objects and cancel the running threads.
My doubt is whether above code works without synchronization logic. If it doesn't how can we add synchronization logic in this case?
The variable should probably be declared volatile. Else it may happen that a thread updates the value to "failed", but the main thread never sees this update. The reasons are explained here:
http://etutorials.org/Programming/Java+performance+tuning/Chapter+10.+Threading/10.6+Atomic+Access+and+Assignment/
It's possible (depending on what the triggering code does) that this is unnecessary, but it's not worth taking the risk.
I want a collection of objects that inherit from Thread; each object running in it's own thread.
I tried extends Thread and called super() thinking that'd ensure a new thread is created; but no... only main is the running thread :(
Everyone tells me, "implement Runnable put the code you want in run() and put it in a thread-object".
I can't do this because of 2-reasons:
My collection-elements aren't of-type Thread and if I polymorph I'll have to change all it's dependencies.
run() can't contain an entire class... right?
So I want to know firstly, if what I want to do is even possible and
secondly, if so, how to do it?
super() just calls the parent constructor (in your case the default Thread constructor). The method to actually start the new thread is start(). As others have said, it's poor design to extend Thread.
Yes, you can create a class that implements Runnable
class MySpecialThread implements Runnable {
public void run() {
// Do something
}
}
and you can start it in a new thread like this:
Thread t = new Thread(new MySpecialThread());
// Add it to a collection, track it etc.
t.start(); // starts the new thread
1- You can use collections of Runnables OR collections of Threads using the example below.
MySpecialThread m = new MySpecialThread();
List<Runnable> runnables = new ArrayList<Runnable>();
runnables.add(m);
List<Thread> threads = new ArrayList<Thread>();
threads.add(new Thread(m));
2- A method can't contain a class, but the above example MySpecialThread is a class that behaves like any other class. You can write a constructor, add methods and fields, etc.
I recommend to use ExecutorService
Let's have a sample code on usage of ExecutorService
import java.util.*;
import java.util.concurrent.*;
public class ExecutorServiceDemo {
public static void main(String args[]){
ExecutorService executor = Executors.newFixedThreadPool(10);
List<Future<Integer>> list = new ArrayList<Future<Integer>>();
for(int i=0; i< 10; i++){
CallableTask callable = new CallableTask(i+1);
Future<Integer> future = executor.submit(callable);
list.add(future);
}
for(Future<Integer> fut : list){
try {
System.out.println(fut.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
executor.shutdown();
}
}
class CallableTask implements Callable<Integer>{
private int id = 0;
public CallableTask(int id){
this.id = id;
}
public Integer call(){
// Add your business logic
return Integer.valueOf(id);
}
}
output:
1
2
3
4
5
6
7
8
9
10
If you want to use Thread instead of ExecutorService, below code should work for you.
import java.util.*;
class MyRunnable implements Runnable{
private int id = 0;
public MyRunnable(int id){
this.id = id;
}
public void run(){
// Add your business logic
System.out.println("ID:"+id);
}
}
public class RunnableList{
public static void main(String args[]){
List<Thread> list = new ArrayList<Thread>();
for ( int i=0; i<10; i++){
Thread t = new Thread(new MyRunnable(i+1));
list.add(t);
t.start();
}
}
}
I was asked to create my own thread pool in an interview where I have to create the number of threads requested by the user. Allow user to submit there task and finally shutdown the pool. I wrote the below program which is working fine in all the cases other than shutdown.
public class ThreadPool
{
public final Queue<Runnable> workerQueue;
private static boolean isrunning = true;
private Thread[] workerThreads;
public ThreadPool(int N)
{
workerQueue = new LinkedList<>();
workerThreads = new Thread[N];
for (int i = 0; i < N; i++) {
workerThreads[i] = new Worker("Pool Thread " + i);
workerThreads[i].start();
}
}
public void shutdown()
{
while(isrunning){
if(workerQueue.isEmpty()){
isrunning = false;
}
}
}
public void submit(Runnable r) throws Exception
{
workerQueue.add(r);
}
private class Worker extends Thread
{
public Worker(String name)
{
super(name);
}
public void run()
{
while (isrunning) {
try {
if(!workerQueue.isEmpty())
{
Runnable r = workerQueue.poll();
r.run();
}
} catch (RuntimeException e) {
e.printStackTrace();
}
}
}
}
}
The Test method I wrote is like below
static public void main(String[] args) throws Exception
{
ClassA a1 = new ClassA();
ClassA a2 = new ClassA();
ClassA a3 = new ClassA();
ClassA a4 = new ClassA();
ClassA a5 = new ClassA();
ClassA a6 = new ClassA();
ThreadPool tp = new ThreadPool(5);
tp.submit(a1);
tp.submit(a2);
tp.submit(a3);
tp.submit(a4);
tp.submit(a5);
///////////////
tp.submit(a6);
tp.shutdown();
}
But the program is never ending, its running always and I have to stop it manually in eclipse. But if I add a simple System.out.print("") in my method shutdown, its working perfrectly(the Program is ended after the execution of all the threads).
Can you please tell me why its working with the sysout and why its not working with out it ?
You have two major problems with your code:
You are using an implementation of Queue that's not synchronized in a multithread environment. This leads to a Race Condition when multiple threads insert/remove from the queue. Please consider using something like:
workerQueue = new ConcurrentLinkedQueue()
You run some very tight loops, one in your Worker.run() method where you're not checking for NPE and not allowing for some "cooldown", and another one in shutdown():
while (isrunning) {
...
Runnable r = workerQueue.poll();
r.run();
...
}
This, coupled with 1, leads to the Queue being emptied without properly updating the size info: ie. isEmpty() returns false but poll() returns null. Your program will become stuck in a loop. This doesn't happen when you add System.out.print() due to different timing specific to your configuration (it can continue to fail in other environments - especially where there are more than 6 cpu cores available).
Now, I started to study Threading and decided to write this class to demonstrate the idea of Multi-Threading but the output wasn't what i want.
i wrote the class as follows : -
import java.util.LinkedList;
class QueueTest extends LinkedList{
int capacity;
LinkedList list;
public QueueTest(int capacity){
this.capacity = capacity;
list = new LinkedList();
}
public synchronized void addElements(int i)throws InterruptedException{
if(list.size() == capacity ){
wait();
}
add(i);
System.out.println("I added : "+i);
notify();
}
public synchronized int getElements() throws InterruptedException{
if(!isEmpty()){
wait();
}
int i = (Integer) list.remove();
System.out.println("I got : "+i);
notify();
return i;
}
}
class Add implements Runnable{
QueueTest t ;
public Add(QueueTest t){
this.t = t;
new Thread(this,"Add").start();
}
#Override
public void run(){
int i = 0;
while(t.size() <= t.capacity){
try{
t.addElements(i++);} catch(InterruptedException e){}
}
}
}
class Remove implements Runnable{
QueueTest t ;
public Remove(QueueTest t){
this.t = t;
new Thread(this,"Remove").start();
}
#Override
public void run(){
while(!t.isEmpty()){
try{
t.getElements();} catch(InterruptedException e){}
}
}
}
public class FullQueue{
public static void main(String[] args){
QueueTest t = new QueueTest(5);
new Add(t);
new Remove(t);
}
}
I expected the output to be like that
i added : 1
i got : 1
i added : 2
i got : 2
... and so on, but i got that output
I added : 0
I added : 1
I added : 2
I added : 3
I added : 4
I added : 5
Because the two threads are running at once there is no guarantee or control at all as to which runs when or in what order.
The get could run completely before the set, the set could run completely first, or they could run all mixed up.
An even interleaving like you display above is very unlikely to happen.
In that case the list has been filled fully by one thread, however the empty thread ran first and exited when it discovered there was nothing in the list.
Add diagnostics to show when each thread starts and ends and you should see that. The results will vary with every run though.
At the moment your notify does nothing as you have nothing waiting. To make the threads alternate then after each write or read you should notify and then wait. You would need to synchronize the whole block though and essentially you end up with a very complicated way to get the same result as one thread running.
this is loaded with race conditions. Note that the Remove thread will exit immediately if there are no elements.