data communication between threads in java - java

I wrote a small program in java to send and receive a data file using two threads. I want the two threads to be in the same class. One thread sends the file and the other thread receives the file. I have wrote the code for it but with few errors. Can you help me figure out the errors in the code. I am a student and a beginner in java, so spare me if there are any silly mistakes.
import java.lang.Thread.*;
import java.io.*;
public class sendques implements Runnable
{
int i=0,c;
static Thread[] t= new Thread[2];
FileInputStream fis=new FileInputStream("ip.jpg");
FileOutputStream fos=new FileOutputStream("output.jpg");
sendques() {
for(i=0;i<2;i++){
t[i]=new Thread(this);
t[i].start();
System.out.println("Threads "+i);
}
}
void run() {
while(true) {
wait();
send();
}
}
void send() {
while((c=fis.read())!=-1) {
t[2].receive(c);
wait();
}
}
void receive(int d) {
while(c!=-1) {
fos.write(d);
t[1].notify();
}
}
public static void main(String arg[]) {
sendques sq=new sendques();
t[1].send();
System.out.println("Quiting..");
}
}

Do not use notify, better use notifyAll, since a liveness failure can occur, named: missed signals. It would make a hard time to correct your code, here is the code for an implementation of producer/consumer with different classes:
BaseBoundedBuffer.java
BoundedBuffer.java
Producer.java
Consumer.java
The Buffer classes are used to store the data shared between producer and consumer. They have their own classes and an example you will find in BoundedBuffer.java. Their is no heavy computing task involved, just passing messages between both.
This is a clean implementation, try to work through it.

Related

Thread working unexpectedly

I have written a simple java program and I was hoping for an output like
go
hello
bye //pause for 2 seconds
hello
But it is giving an output like
go
bye
hello //pause for 2 sec
hello
Programme:
class Tread{
public static void main(String[] args){
Hello h= new Hello();
Thread t= new Thread(h);
System.out.println("go");
t.start();
System.out.println("Bye");
}
}
class Hello implements Runnable{
public void run(){
System.out.println("hello");
try{
Thread.sleep(2000);
}
catch(Exception e){ }
System.out.println("hello");
}
}
Please, can anybody tell me why i am not getting the desired otput?
The result is unpredictable since 2 threads try to write something on the output simultaneously. The JVM specs do not specify the order of the operations:
you have the main thread that starts another thread
after that, the main thread and the other thread both print something.
So, all of this is implementation dependant: somebody may use another JVM, one day, and/or another operating system, and he could then have another behaviour. With your JVM, on your environment, you may encounter millions of run of this program writing output in the same order. But it does not mean that it will never change in the future.
If you want the sequence of operations to be done according to a particular order, you need to use some locks, or synchronized keyword to access resources.
Thinking it will always behave the same often leads to mistakes, that happen only occasionally, and that we call race conditions.
I guess because it is on another thread, independent from main program.
Try this:
public static void main(String[] args){
Hello h= new Hello();
Thread t= new Thread(h);
System.out.println("go");
t.start();
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println("Bye");
}
}
class Hello implements Runnable{
public void run(){
System.out.println("hello");
try{
Thread.sleep(2000);
}
catch(Exception e){}
System.out.println("hello");
}
}

Stuck writing to JCSP channel

I have this really simple JCSP(Java Communicating Sequential Processes) code sample in which I'm trying to write an integer to a One2OneInt channel and then read it.
package jcsp;
import org.jcsp.lang.*;
public class JCSP {
public static void main(String[] args) {
One2OneChannelInt chan = Channel.one2oneInt();
chan.out().write(5);
System.out.println("Written...");
System.out.println(chan.in().read());
}
}
It seems that value never gets written on the channel and program just keeps running. "Written..." is never printed out.
So I learned about BlockingQueue and its implementation SynchronousQueue. As stated here, SynchronousQueue works in similar way in which CSP Channels work. This helped me realize what was wrong with my code. Simply put, you can't write and read from channel in same process. Channel is way for processes to communicate.
Similarly to SynchronousQueue's put() which will wait for other process to call take(), CSP Channel's write() which will wait for corresponding read() to be called. The difference is that CSP Channels have objects ChannelOutput and ChannelInput through which objects are written and red. Conversely, you can call put and take directly on instance of SynchronousQueue. Personally, I find SynchronousQueue much easier to understand, which probably relates to JCSP not being very popular.
Still, if you're interested how I made the above code work in JCSP, here it is:
public static class Process1 implements CSProcess {
private ChannelOutputInt output;
public Process1(ChannelOutputInt out) {
output = out;
}
#Override
public void run() {
for (int i = 0; i < 1; i++) {
System.out.println("Written...");
output.write(5);
}
output.write(-1);
}
}
public static class Process2 implements CSProcess {
private ChannelInputInt input;
public Process2(ChannelInputInt in) {
input = in;
}
#Override
public void run() {
int x = 0;
while ((x = input.read()) > 0) {
System.out.println(x);
}
}
}
public static void main(String[] args) {
One2OneChannelInt chan = Channel.one2oneInt();
Process1 process1 = new Process1(chan.out());
Process2 process2 = new Process2(chan.in());
Parallel parallel = new Parallel();
parallel.addProcess(process1);
parallel.addProcess(process2);
parallel.run();
}
The problem is the channel is unbuffered, so your write() call will block until another process reads from the channel. As soon as another process calls read(), 'Written...' will be printed out.
A BlockingQueue with a capacity of 0 behaves similarly to a JCSP channel

Can I do 'global Shared Object' in Java?

I have two CLASS(each has a thread), and I want to create a queue shared between them. So one class could write some bytes to the queue, and the other can read from the SAME queue.
I tried static, and here are my codes:
public class ShareQueueTest {
public static final BlockingQueue<byte[]> memshare= new ArrayBlockingQueue<>(1000);
public static void main(String[] args){
Thread a = new Thread(){public void run(){
for(;;){
try {
memshare.put(new byte[20]);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(memshare.size());
}
}};
a.start();
}
}
And the other class is simple read from this queue.
public class ShareQueueTest2 {
public static void main(String[] args){
Thread a = new Thread(){public void run(){
for(;;){
System.out.println(ShareQueueTest.memshare.size());
}
}};
a.start();
}
}
I run it. Though one thread is putting bytes in this queue, the other is still saying the queue is empty all the time. So clearly they are referred to the different things.
ALL the thing happens in local machine.
As this question is simplified from a network scenario, so for some reason, I don't want another class to manipulate those two threads, they are blind to each other. Perhaps the only thing they know for each other is that each thread running on the same local machine, plus, they know the port numbers of the other. Under such condition, I need some methodologies to create a data structure which both of them can 'see'.
I also think of using memory address. Like one class get the memory address of the object, and the other get the object from the address and cast it to the correct data structure. Is it possible in java?
Any help will be appreciated!
Since both of your classes have a main method, it appears that you may be running these two classes in separate processes (instances of the JVM)
If you call ShareQueueTest2.main(...) from ShareQueueTest.main, it should work
If you call the two classes separately, it would spawn two separate JVMs which are two separate processes. The thread cannot communicate across processes via a shared queue.
You need to start both the threads from the same code as the other answers point out. Then you can access the shared variables and see the changes done by one thread get reflected in the other thread.
Try this :
public class ShareQueueTest {
public static final BlockingQueue<byte[]> memshare= new ArrayBlockingQueue<>(1000);
public static void subMain(String[] args){
Thread a = new Thread(){public void run(){
for(;;){
try {
memshare.put(new byte[20]);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(memshare.size());
}
}};
a.start();
}
}
public class ShareQueueTest2 {
public static void subMain(String[] args){
Thread a = new Thread(){public void run(){
for(;;){
System.out.println(ShareQueueTest.memshare.size());
}
}};
a.start();
}
}
public class Launch
{
public static void main( String[] args)
{
ShareQueueTest1.subMain(args);
ShareQueueTest2.subMain(args);
}
}

Socket accept and multiple threads

I have this issue I have no idea how to resolve and I'm at the brink of insanity. Programming, eh? :/
Anyway, I have a server which has a thread to send users all the info it needs to (which needs to run constantly) and another thread that awaits new server connections. My problem is once socket.accept() is called, the other thread doesn't execute.
So, to explain with code:
class Thread1 extends Thread {
public void run() {
while(true)
{
s=socket.accept();
}
}
class Thread2 extends Thread {
public void run() {
//do stuff
System.out.println("spam");
}
}
public static void main(String[] args)
{
Thread1 t1 = new Thread1();
t1.start();
t1.Thread2 t2 = t1.new Thread2();
t2.start();
}
}
Assume all other required member variables are present, no compile errors and connection functionality works fine. Just 'Thread2' executes only once.
So my question is, how do I resolve this problem?
Thanks in advance,
Tim.
I think you have a basic misunderstanding of threads. Let's see if we can clear that up.
Threads are simply another pipeline of execution. Think of them like tasks with a particular set of instructions. Once the task is done, the thread returns. Pretty simple idea, right?
In your example, Thread1 has an endless loop, which makes sense that it does run infinitely and does accept clients indefinitely.
However, Thread2 simply outputs some text and returns. There's nothing telling it to 'keep spinning'.
Within your main(), even though Thread2 is an inner class of Thread1 (which is kind of bad form to begin with, might I add) it doesn't actually force the thread to keep running.
You'll probably want to add a Queue to your server class that holds new sockets, and have Thread2 loop and check for entries.
Further Reading
Firstly, take a look at the Thread class. Its constructor takes a Runnable, so that's all you should be implementing when working with threads (i.e. class Foo implements Runnable and then new Thread(new Foo())).
If sockets are your fancy, perhaps some further reading on socket-server architecture and even about protocol design would be something you'd benefit from.
Some suggestions
never extend a Thread as it's a good way to confuse yourself. Never nest a Thread inside another Thread unless you really like confusion.
if you want to run a thread for each socket, then create a new thread for each socket in the loop.
Try the following (Note: You can add IOException handling code)
class SocketAcceptor implements Runnable {
public void run() {
while(true) {
Socket s=socket.accept();
SocketHandler sh = new SocketHandler(s);
new Thread(sh).start();
}
}
}
class SocketHandler implements Runnable {
final Socket s;
SocketHandler(Socket s) { this.s = s; }
public void run() {
System.out.println("New connection " + s);
s.close();
}
}
A better solution would be to use a Thread pool. e.g. An ExecutorService, but I would get this working first.

Trying to use 100 thread at a time.

I am creating one Testing Tool which is test the performance of the Web-Services. Now i want to test performance of my tool when 100 user hit this web service.
In Current, I create one thread which heat and show me request-response details in log. But i need to create 100 threads which work parallel and show me request-response of 100 threads.
My question is how to create 100 parallel thread's. Here i try to create 100 thread parallel but when i run this program it will not call run() method.
Here is my code.
public class Main implements Runnable
{
int counter= 0;
public static void main(String args[]) throws Throwable
{
Thread t[]=new Thread[100];
for (int j=0; j<100;j++)
{
t[j]=new Thread();
t[j].start();
}
}
public void run()
{
try {
System.out.println("thread "
+Thread.currentThread().getName()+" step "+counter++);
}
catch (Throwable t) {
t.printStackTrace();
}
}
}
Give me some hint or reference. I don't understand where i wrong.
Thanks in Advance.
You are not instantiating your thread class - which happens to be Main.
Your class should be like:
public class Main extends Thread {
int counter= 0;
public static void main(String args[]) throws Throwable {
Main t[] = new Main[100];
for (int j=0; j<100;j++) {
t[j] = new Main();
t[j].start();
}
}
public void run() {
try {
System.out.println("thread " + Thread.currentThread().getName()+" step "+counter++);
}
catch (Throwable t) {
t.printStackTrace();
}
}
}
You probably meant t[j]=new Thread(new Main())
I suggest you use an ExecutorService to manage your threads and you can submit your Runnable as a task to this pool.
I suggest you to use Apache JMeter for webservices testing purpose. It already has parallel threads feature for request/response.
Anyway:
To create new thread use constructor:
Thread(Runnable target)
As you can see, thread implements runnable, another way is just override run method.
public class Thread implements Runnable

Categories

Resources