i need help, i try to use synchronization thread in java but it can't run...
i have two class with thread like this
for(int j=0;j<idW.length;j++){
webtext = d.getWebText(idW[j]);
ThreadPrepo tpo =new ThreadPrepo(webtext, host[j%jumhost], "server", 1099,idW[j]);
Thread t1=new Thread(tpo);
t1.start();
}
//thread untuk setfitur tanpa rmi
int ukuran=idW.length;
ProsesSetfitur pro=new ProsesSetfitur(idW);
Thread t2=new Thread(pro);
t2.start();
this is the code in class threadprepo :
public class ThreadPrepo implements Runnable{
String host,server,c,webtext;
int port,idweb;
DataDB db=new DataDB();
public ThreadPrepo(String webtext,String host,String server,int port,int idweb){
this.webtext=webtext;
this.host=host;
this.server=server;
this.port=port;
this.idweb=idweb;
}
#Override
public void run(){
preponi();
}
public synchronized void preponi(){
try{
System.out.println("hostnya :"+host);
Registry reg=LocateRegistry.getRegistry(host,port);
Sportrmijob rmi=(Sportrmijob) reg.lookup("server");
rmi.SetInput(webtext);
List l=rmi.getresult();
String[] hasilprep=new String[l.size()];
for(int k=0;k<l.size();k++){
hasilprep[k]=l.get(k).toString();
}
db.insertWordney(idweb, hasilprep);
String [][] frekdb=db.getFrekDB(idweb);
db.doinsertfrek(idweb,frekdb);
}
catch(Exception e){
System.out.println("error di class threadprepo "+e.getMessage());
}
}
}
and then this is code in class prosesSetFitur
public class ProsesSetfitur implements Runnable{
DataDB d=new DataDB();
int []idweb;
public ProsesSetfitur(int[]idweb){
this.idweb=idweb;
}
#Override
public void run(){
try{
Thread.sleep(500);
setfitur();
}
catch(Exception e){
System.out.println("error setfitur "+e.getMessage());
}
}
public synchronized void setfitur() throws InterruptedException{
System.out.println("(proses setfitur)");
String []allkata;
String fitur;
String []fiturs=new String[15];
String []kata_kata=new String[15];
System.out.println("nilai iD="+idweb.length);
for(int s=0;s<idweb.length;s++){
//System.out.println("IDWEEEEEEEEEEB"+idweb[s]);
allkata=d.getUrutanKata(idweb[s]);
for(int u=0;u<15;u++){
// System.out.println("PERULANGAN U KE"+u);
if(u<=4){
fitur="T";
//System.out.println("kata ke" +u+" = "+allkata[u]+" fiturnya = "+fitur);
kata_kata[u]=allkata[u];
fiturs[u]=fitur;
}
else if(u>4&&u<10){
fitur="S";
//System.out.println("kata ke"+u+" = "+allkata[u]+" fiturnya = "+fitur);
kata_kata[u]=allkata[u];
fiturs[u]=fitur;
}
else if(u>=10&&u<15){
fitur="R" ;
//System.out.println("kata ke"+u+" = "+allkata[u]+" fiturnya = "+fitur);
kata_kata[u]=allkata[u];
fiturs[u]=fitur;
}
}
d.insertfitur(idweb[s], kata_kata, fiturs);
}
}
can anyone give me solution to solve this problem...why thread in class ProsesSetFitur is execute first?how synchronization thread can work?please help...
public void run(){
try{
Thread.sleep(500);
setfitur();
}
run() method called only once when you start a thread. Again for different thread run() method will be different and call only once for the thread.
Also your preponi() and setfitur() called single time from run(). thats why you should not put synchronized modifier before preponi() and setfitur().
you should use synchronized when multiple thread access same resource or same function or same code block to make it thread safe.
Thread []tArray=new Thread[idW.length];
for(int j=0;j<idW.length;j++)
{
webtext = d.getWebText(idW[j]);
ThreadPrepo tpo =new ThreadPrepo(webtext, host[j%jumhost], "server", 1099,idW[j]);
tArray[j]=new Thread(tpo);
tArray[j].start();
tArray[j].join();
}
//thread untuk setfitur tanpa rmi
int ukuran=idW.length;
ProsesSetfitur pro=new ProsesSetfitur(idW);
Thread t2=new Thread(pro);
t2.start();
A thread sleep may be a pragmatic solution but it is not a guarantee for thread synchronization. To coordinate thread actions you should go for the basic wait/notify pattern whereas the threads uses conditions to perform certain actions. For a good introduction read this articles.
http://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html
http://www.journaldev.com/1037/java-thread-wait-notify-and-notifyall-example
Related
public class Alternate {
static Boolean mutex = true;
public static void main(String[] args) {
Thread t1 = new Thread(new Odd(mutex));
Thread t2 = new Thread(new Even(mutex));
t1.start();
t2.start();
}
}
class Odd implements Runnable{
Boolean mutex;
Odd( Boolean mutex){
this.mutex=mutex;
}
#Override
public void run() {
try {
synchronized(mutex){
while(mutex){
mutex.wait();
}
System.out.println("odd");
mutex=true;
mutex.notifyAll();
Thread.sleep(500);
}
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class Even implements Runnable{
Boolean mutex;
Even( Boolean mutex){
this.mutex=mutex;
}
#Override
public void run() {
try {
synchronized(mutex){
while(!mutex){
mutex.wait();
}
System.out.println("even");
mutex=false;
mutex.notifyAll();
Thread.sleep(500);
}
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}
The error is
java.lang.IllegalMonitorStateException
at java.lang.Object.notifyAll(Native Method)
at com.test.concurrency.Even.run(Alternate.java:55)
at java.lang.Thread.run(Thread.java:722)
I am not able to figure out the reason for the error. I am calling notifyAll() from synchronised context and calling it from the correct object.
You're changing the lock out from under your threads. Every time you set your boolean to something, that's a different object; the code
mutex=true;
mutex.notifyAll();
sets mutex to a different object from the one the thread synchronized on (so the thread hasn't acquired the monitor for it), then it calls notifyAll on the new object.
Use a single lock and don't change it.
Locking on Booleans, numeric wrappers, or Strings is too error-prone and should be avoided. Not only can you end up with the error you're seeing, but other unrelated parts of the application (maybe written by somebody else following the same practice) could be locking on the same object and causing mysterious problems. Booleans, number wrappers, and strings are available to everything in the JVM. It's better to use a lock that is constrained in scope so that nothing else in your application can acquire it.
Often it's best to use a dedicated lock, something you don't use for any other purpose. Overloading something with different uses can cause trouble too easily.
Corrected Code if anyone needs
import java.util.concurrent.atomic.AtomicInteger;
public class Alternate {
static final AtomicInteger mutex = new AtomicInteger(0);
public static void main(String[] args) {
Thread t1 = new Thread(new Odd());
Thread t2 = new Thread(new Even());
t1.start();
t2.start();
}
static class Odd implements Runnable{
#Override
public void run() {
try {
for(int i=0;i<10;i++){
synchronized(mutex){
while(mutex.get()==1){
mutex.wait();
}
System.out.println("odd");
mutex.compareAndSet(0, 1);
mutex.notifyAll();
}
}
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}
static class Even implements Runnable{
#Override
public void run() {
try {
for(int i=0;i<10;i++){
synchronized(mutex){
while(mutex.get()==0){
mutex.wait();
}
System.out.println("even");
mutex.compareAndSet(1, 0);
mutex.notifyAll();
}
}
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
In my app I start multiple media downloads in Threads via ThreadPoolExecutor. Now I want to be able to pause particular download threads. How I can do this?
well I'm not sure how you have implemented your code, so I'm just guessing here.
One way of doing this, by keeping track of your Threads,
for example create a Map :
Map<String,Thread> threads=new HashMap<String,Thread>();// ensure each Thread has a unique id, in this case its supposedly a String. then you can control them from outside your thread pool.
here is a hacked implementation:
public class hello{
public static void main(String...strings )throws Exception{
ExecutorService executor = Executors.newFixedThreadPool(5);
Map<String,Thread> threads=new HashMap<String, Thread>();
for(int i=0;i<5;i++){
Thread t = new myRunnable((i+1) +" ");
threads.put((i+1)+"", t);
executor.execute(t);
}
Thread.sleep(2000);
((myRunnable)threads.get("1")).isSuspened=true;
}
private static class myRunnable extends Thread{
String a;
public boolean isSuspened=false;
public myRunnable(String a) {
this.a=a;
// TODO Auto-generated constructor stub
}
#Override
public void run(){
while(true){
if(isSuspened){
continue;
}
try{
System.out.println(a);
Thread.sleep(2000);
}catch(Exception e){}
}
}
}
}
//The below code is throwing illegalmonitorstate exception.
public class Multithreading implements Runnable {
static int i=0;
public boolean ist1=true;
public boolean ist2=false;
public static void main (String args[]){
Multithreading ins= new Multithreading();
Thread t1 =new Thread(ins);
Thread t2 =new Thread(ins);
t1.setName("Even");
t2.setName("ODD");
t1.start();
t2.start();
}
#Override
// Wanted to right run method used by two threads to print
// even and odd number in sequence
public void run() {
while(i<=9){
try{
if(Thread.currentThread().getName().contains("Even")&& i%2==0){
System.out.println(Thread.currentThread().getName()+"________"+i);
i=i+1;
Thread.currentThread().wait(100);
}
// due to wait is not used with synchronized but
// i am not able to correct it
if(Thread.currentThread().getName().contains("ODD") && i%2>=1){
System.out.println(Thread.currentThread().getName()+"________"+i);
i=i+1;
Thread.currentThread().wait(100);
//System.out.println(e);
}
}catch(Exception e){
System.out.println(e);
}
}
}
}
To pause a thread, you need to use Thread.sleep() in your case instead of wait().
So, i apologize for the title. It's quite hard to explain in one sentence what i would like to do if you have no idea on how it is called.
So assume i can only use primitive thread functions (wait, notify, no concurrent package)
The program has 3 threads, all of them are the same and are called by the main thread. They behave normally until one of the three get an exception and so it must wait for the end of the remaining 2 threads in order to start a recovery process.
I was thinking about a static variable but I'm not really sure about it, i would love to keep it as simple as possible.
Each thread starts at the same time.
I don't see any reason why you can't use a static variable like you suggest. Here's how I would do it with an inner class...
private static boolean running = true;
public void test26546397() {
while (true) {
Thread t1 = new Thread(new MyRunnable());
Thread t2 = new Thread(new MyRunnable());
Thread t3 = new Thread(new MyRunnable());
t1.start();
t2.start();
t3.start();
try {
t1.join();
t2.join();
t3.join();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
running = true;
// Do recovery
}
}
public class MyRunnable implements Runnable {
#Override
public void run() {
while (running) {
try {
// doStuff
} catch (Exception ex) {
running = false;
}
}
}
}
I would of course replace the while (true) with something a little more suitable.
I think you need java.concurrent.CountdownLatch, however if the java.concurrent package is not available to you can code this yourself using Object.wait/notify and synchronized blocks.
The latch can then be decremented in a finally {} on each Thread, this will be run if the Thread completes, or an exception occurs.
Your main program then just needs to wait for count to become 0.
public class StackOverflow26546397 {
static class CountdownLatch {
private int count;
private Object monitor = new Object();
public CountdownLatch(int count) {
this.count = count;
}
public void countDown() {
synchronized (monitor) {
count--;
monitor.notifyAll();
}
}
public void await() throws InterruptedException {
synchronized (monitor) {
while (count > 0) {
monitor.wait();
}
}
}
}
static class Job implements Runnable {
private CountdownLatch latch;
public Job(CountdownLatch latch) {
this.latch = latch;
}
#Override
public void run() {
try {
// do work.
Thread.sleep((long) (Math.random() * 3000d));
} catch (InterruptedException e) {
//
} finally {
latch.countDown();
}
}
}
public static void main(String[] args) throws InterruptedException {
CountdownLatch latch = new CountdownLatch(3);
new Thread(new Job(latch)).start();
new Thread(new Job(latch)).start();
new Thread(new Job(latch)).start();
latch.await();
System.out.println("All threads finished");
}
}
Not sure what you are trying to do but this is as simple as I can think of (just native concurrency):
Create a static or shared volatile boolean
private static volatile boolean exceptionOccured=false
Set the above to 'true' when exception occurs:
....}catch(Exception e){
exceptionOccured=true;
}
Check this periodically in you normal thread flow:
if (exceptionOccured)
//enter you synchronized call here
the synchronized method could look something like:
public synchronized void checkAndRecover(){
//decrement a counter or other logic to identify which is the last Thread and then
//perform any recovery logic
}
How Join method work in Thread. If write join method in run method then its going to deadloack. Just need to information why its happening.
Code Snipet:
public class ThreadSchuduling extends Thread{
static ThreadSchuduling threadObj3;
public ThreadSchuduling(){
System.out.println("Default Constructor");
}
public ThreadSchuduling(String name){
System.out.println("Parameter Constructor");
}
public void run(){
try{
threadObj3.join();
}catch(Exception e){
System.out.println("Error in RUN "+e);
}
System.out.println(Thread.currentThread().getName());
for(int i = 0; i < 10; i++){
System.out.println("Value is = "+i);
}
}
public static void main(String[] args) {
ThreadSchuduling threadObj1 = new ThreadSchuduling("Thread1");
ThreadSchuduling threadObj2 = new ThreadSchuduling("Thread2");
threadObj3 = new ThreadSchuduling("Thread3");
ThreadSchuduling threadObj4 = new ThreadSchuduling("Thread4");
threadObj1.start();
threadObj2.start();
threadObj3.start();
System.out.println("Thread 3 is started");
threadObj4.start();
try{
threadObj3.join();
}catch(Exception e){
System.out.println("Errpr "+e);
}
System.out.println("Main Method completed");
}
}
I just want to complete the thread3 before the thread1 and thread2
You haven't explained what threadObj3 is... is that a reference to the same thread? If so, it's understandable that it will deadlock - it's waiting until it's finished, which it won't do because it's waiting!
What are you actually trying to achieve?
OMG,threadObj3 is always waiting by itself,if you want to complete thread3 before thread1 and thread2, you can set the priority,or it's hard to make sure thread3's execution before other thread.