Are you king of threads?

We were implementing a producer consumer thing and my partner dropped out leaving me with a huge load of problems.

Threads are not exactly my cup of tea. All I want to do is to make the application pause as long as the time printed from the keyboard.

The time pausing should be specified for consuming the products and producing them. Also how long the buffer should hold after an item is inserted there. I don't think I'm that far from the solution, but nothing happens when I try to run it.

I apologise for the amount of code, but maybe it was nessecary to get the whole picture?

import java.awt.*;

import javax.swing.*;

import javax.swing.Timer;

import java.util.*;

import java.awt.*;

import java.awt.event.*;

publicclass Producerextends Location

implements Runnable

{

public Thread aktivitet=new Thread(this);

private ProductTypeList canProducera;

private ProductList harProducerat;

private Color color;

private String producerStatus="";

private String producerName;

private JPanel prodPanel;

private JPanel prodLetterHasPanel;

private Label prodSifTimerLabel =new Label ("0");

private Timer t;

private Label prodStatusLabel;

private Buffer buffer;

private SpelFrame frame;

public Producer(Color arg_color, String name, ProductTypeList canProduc,Buffer buffer1)

{

this.producerName=name;

this.color = arg_color;

this.canProducera= canProduc;

this.harProducerat=new ProductList();

this.producerStatus="WAITING_ON_BUFFER_NOT_FULL";

System.out.println(this.producerName +" ");

this.buffer= buffer1;

this.t =new Timer(100,new TickLyssnare(prodSifTimerLabel));

t.start();

aktivitet.start();

}

publicvoid addFrame(SpelFrame fr)

{

this.frame=fr;

}

publicvoid run()

{

while(!Thread.interrupted())

{

try

{

Thread.sleep(2000);

Product produkt= produce();

this.buffer.put(produkt);

}

catch(InterruptedException avbruten)

{

break;

}

}

}

public Color getProducerColor()

{

return this.color;

}

public ProductList getHasProducet()

{

return this.harProducerat;

}

private ProductType getRandomProductType()

{

int rand_tal= (int) (Math.random()*this.canProducera.getListLength());

return this.canProducera.getObjectByIndex(rand_tal);

}

public Product produce()

{

Product newProduct =new Product(this, this.getRandomProductType());

this.harProducerat.setProduct(newProduct);

this.producerStatus="PRODUCING";

this.prodStatusLabel.setText(this.producerStatus);

this.addProductTillProducerPanel(newProduct);

//this.buffer_Manipulation(newProduct);

return newProduct;

}

publicvoid buffer_Manipulation(Product product)

{

System.out.println("Remove fr錸 "+this.producerName +" "+product.getType().present_me()+

" till buffer");

if(buffer.is_Buffer_Full())

{

this.producerStatus="WAITING_ON_BUFFER_NOT_FULL";

this.prodStatusLabel.setText(this.producerStatus);

}

else

{

System.out.println("Remove fr錸 "+this.producerName +" "+product.getType().present_me()+

" till buffer");

this.producerStatus="MANIPULATING_BUFFER";

this.prodStatusLabel.setText(this.producerStatus);

product.moveToBuffer(this.buffer);

buffer.uppdateBufferInformationPanel();

}

}

public JPanel producerPanel()

{

this.prodPanel=new JPanel();

prodPanel.setLayout(new GridLayout(8,1));

Label prodLabel =new Label(this.producerName);

prodLabel.setForeground(Color.WHITE);

prodLabel.setBackground(this.color);

prodPanel.add(prodLabel);

this.prodStatusLabel =new Label(this.producerStatus);

prodPanel.add(prodStatusLabel);

Label prodCanLabel =new Label("Can produce: ");

prodPanel.add(prodCanLabel);

Label prodLetterCanLabel =new Label(canProducera.presenteraMe());

prodLetterCanLabel.setForeground(this.color);

prodPanel.add(prodLetterCanLabel);

Label prodTimerLabel =new Label ("Timer: ");

prodPanel.add(prodTimerLabel);

this.prodSifTimerLabel.setForeground(this.color);

prodPanel.add(this.prodSifTimerLabel);

Label prodHasLabel =new Label("Has produced:");

prodPanel.add(prodHasLabel);

this.prodLetterHasPanel =this.harProducerat.presenteraMeJPanel();

prodPanel.add(this.prodLetterHasPanel);

prodPanel.setBorder(BorderFactory.createLineBorder(this.color));

return this.prodPanel;

}

publicvoid addProductTillProducerPanel(Product product)

{

Label l =new Label(product.getType().present_me());

l.setForeground(this.color);

this.prodLetterHasPanel.add(l);

this.frame.setVisible(true);

}

class TickLyssnareimplements ActionListener

{

privateint tick;

privateint sec;

private Label lab;

public TickLyssnare(Label tidLabel)

{

this.lab= tidLabel;

this.tick= 0;

this.sec= 0;

}

publicvoid actionPerformed(ActionEvent e)

{

tick= tick + 1;

if (tick== 10)

{

tick= 0;

sec++;

System.out.println(" Tick Lyssnare: "+this.sec);

this.lab.setText(""+sec);

}

}

}

}

--

import java.awt.*;

import javax.swing.*;

import javax.swing.Timer;

import java.util.*;

import java.awt.*;

import java.awt.event.*;

publicclass Consumerextends Location

implements Runnable

{

public Thread aktivitet =new Thread(this);

private ProductTypeList canConsum;

private ProductList hasConsumt;

private String consumerStatus ="";

private String consumerName;

private JPanel consPanel;

private Label consStatusLabel;

private Label consSifTimerLabel=new Label ("0");

private JPanel consLetterHasPanel;

private Timer t;

private SpelFrame frame;

private Buffer buffer;

privatelong tid;

public Consumer(String name,ProductTypeList argCanConsum, Buffer buffer1)

{

this.consumerName= name;

this.canConsum = argCanConsum;

this.hasConsumt =new ProductList();

this.consumerStatus ="WAITING_ON_BUFFER_ACCESS";

this.buffer= buffer1;

this.t =new Timer(100,new TickLyssnare(consSifTimerLabel));

t.start();

aktivitet.start();

}

publicvoid run()

{

while (!Thread.interrupted())

{

try{

Thread.sleep(2000);

buffer.take(this);

}

catch (InterruptedException avbruten)

{

break;

}

}

}

publicvoid addFrame(SpelFrame fr)

{

this.frame=fr;

}

publicvoid consumera(Buffer buffer)

{

if(!buffer.is_Buffer_Empty())

{

this.consumerStatus="MANIPULATING_BUFFER";

this.consStatusLabel.setText(this.consumerStatus);

ProductList bufferList= buffer.getBufferList();

for(int i=0; i< bufferList.getListLength();i++)

{

Product product= bufferList.getObjectByIndex(i);

if(this.isInCanComsum(product.getType()))

{

product.moveToConsumer(this);

this.addProductTillConsumerPanel(product);

System.out.println(product.getType().present_me()+" har consumerat");

buffer.uppdateBufferInformationPanel();

this.consumerStatus="CONSUMING";

this.consStatusLabel.setText(this.consumerStatus);

}

}

}

else

{

this.consumerStatus="WAITING_ON_BUFFER_NOT_EMPTY";

this.consStatusLabel.setText(this.consumerStatus);

}

}

publicvoid addProductTillConsumerPanel(Product product)

{

Label l =new Label(product.getType().present_me());

l.setForeground(product.getProducer().getProducerColor());

this.consLetterHasPanel.add(l);

this.frame.setVisible(true);

}

publicboolean isInCanComsum(ProductType prType)

{

return this.canConsum.isInTypeList(prType);

}

publicvoid addHasConsumt(Product product)

{

this.hasConsumt.setProduct(product);

}

publicvoid setConsumerStatus(String status)

{

this.consumerStatus=status;

}

public String getConsumerStatus()

{

return this.consumerStatus;

}

publicvoid consume(Product new_product)

{

this.hasConsumt.setProduct(new_product);

}

publicvoid buffer_Manipulation()

{

}

public JPanel consumerPanel()

{

this.consPanel=new JPanel();

consPanel.setLayout(new GridLayout(8,1));

Label consLabel =new Label(this.consumerName);

consLabel.setForeground(Color.WHITE);

consLabel.setBackground(Color.MAGENTA);

consPanel.add(consLabel);

this.consStatusLabel =new Label (this.consumerStatus);

consPanel.add(consStatusLabel);

Label consCanLabel =new Label("Can consume: ");

consPanel.add(consCanLabel);

Label consLetterCanLabel =new Label(canConsum.presenteraMe());

consPanel.add(consLetterCanLabel);

Label consHasLabel =new Label("Has consumed:");

consPanel.add(consHasLabel);

this.consLetterHasPanel =this.hasConsumt.presenteraMeJPanel();

consPanel.add(consLetterHasPanel);

Label consTimerLabel =new Label ("Timer: ");

consPanel.add(consTimerLabel);

consPanel.add(this.consSifTimerLabel);

consPanel.setBorder(BorderFactory.createLineBorder(Color.MAGENTA));

return this.consPanel;

}

class TickLyssnareimplements ActionListener

{

privateint tick;

privateint sec;

private Label lab;

public TickLyssnare(Label tidLabel)

{

this.lab= tidLabel;

this.tick= 0;

this.sec= 0;

}

publicvoid actionPerformed(ActionEvent e)

{

tick= tick + 1;

if (tick== 10)

{

tick= 0;

sec++;

System.out.println(" Tick Lyssnare: "+this.sec);

this.lab.setText(""+sec);

}

}

}

}

--

import javax.swing.*;

import javax.swing.Timer;

import java.util.*;

import java.awt.*;

import java.awt.event.*;

publicclass Bufferextends Location

{

private ProductList bufferList;

private String ss1;

private String ss2;

private Label l1,l2,l3, l4, lb1,lb2, lb3, lb4;

private DrawingArea dArea;

private SpelFrame frame;

publiclong tid;

public Buffer()

{

this.bufferList =new ProductList();

}

publicsynchronizedvoid put(Product product)

{

while (this.bufferList.getListLength()>=4)

while (bufferList.isEmty())

try{Thread.sleep(SpelFrame.setTime(tid));}

catch (InterruptedException e)

{

return;

}

product.getProducer().buffer_Manipulation(product);

notify();

this.frame.setVisible(true);

}

publicsynchronizedvoid take(Consumer consumer)

{

while (this.bufferList.isEmty())

try{Thread.sleep(SpelFrame.setTime(tid));}

catch (InterruptedException e)

{

return;

}

consumer.consumera(this);

this.frame.setVisible(true);

}

publicvoid uppdateBufferInformationPanel()

{

if(this.is_Buffer_Empty())

{

ss1 ="* is empty";

}

else

{

ss1 ="* is not empty";

}

if(this.is_Buffer_Full())

{

ss2 ="* is full";

}

else

{

ss2 ="* is not full";

}

this.dArea.changeDrawingArea(ss1, ss2,"Buffer");

int buffLength= bufferList.getListLength();

if (buffLength>0)

{

lb1.setText(bufferList.getObjectByIndex(0).present_me());

lb1.setForeground(

bufferList.getObjectByIndex(0).getProducer().getProducerColor());

}

else

{

lb1.setText("");

}

if (buffLength>1)

{

lb2.setText(bufferList.getObjectByIndex(1).present_me());

lb2.setForeground(

bufferList.getObjectByIndex(1).getProducer().getProducerColor());

}

else

{

lb2.setText("");

}

if (buffLength>2)

{

lb3.setText(bufferList.getObjectByIndex(2).present_me());

lb3.setForeground(

bufferList.getObjectByIndex(2).getProducer().getProducerColor());

}

else

{

lb3.setText("");

}

if (buffLength>3)

{

lb4.setText(bufferList.getObjectByIndex(3).present_me());

lb4.setForeground(

bufferList.getObjectByIndex(3).getProducer().getProducerColor());

}

else

{

lb4.setText("");

}

}

public ProductList getBufferList()

{

return this.bufferList;

}

publicboolean is_Buffer_Empty()

{

return this.bufferList.isEmty();

}

publicboolean is_Buffer_Full()

{

if(this.bufferList.isEmty())

{

returnfalse;

}

if(this.bufferList.getListLength()==4)

{

returntrue;

}

elsereturnfalse;

}

publicvoid addToBuffer(Product product)

{

bufferList.setProduct(product);

System.out.println(product.getType().present_me()+" har addit till buffer ");

}

publicvoid deleteFromBuffer(Product product)

{

this.bufferList.remove_Product(product);

System.out.println(product.getType().present_me()+" has removed from the buffer");

}

public JPanel presentMePanel()

{

JPanel bufferPanel =new JPanel();

bufferPanel.setLayout(new GridLayout(2,1));

if(this.is_Buffer_Empty())

{

ss1 ="* is empty";

}

else

{

ss1 ="* is not empty";

}

if(this.is_Buffer_Full())

{

ss2 ="* is full";

}

else

{

ss2 ="* is not full";

}

this.dArea =new DrawingArea(ss1, ss2,"Buffer");

bufferPanel.add(dArea);

JPanel bufferInnePanel =new JPanel();

bufferInnePanel.setLayout(new GridLayout(8,1));

JPanel bufferStorInnePanel =new JPanel();

bufferStorInnePanel.setLayout(new GridLayout(1,3));

int buffLength= bufferList.getListLength();

l1 =new Label("Product 1");

bufferInnePanel.add(l1);

if (buffLength>0)

{

lb1 =new Label(bufferList.getObjectByIndex(0).present_me());

lb1.setForeground(

bufferList.getObjectByIndex(0).getProducer().getProducerColor());

}

else

{

lb1 =new Label("");

}

bufferInnePanel.add(lb1);

l2 =new Label("Product 2");

bufferInnePanel.add(l2);

if (buffLength>1)

{

lb2 =new Label(bufferList.getObjectByIndex(1).present_me());

lb2.setForeground(

bufferList.getObjectByIndex(1).getProducer().getProducerColor());

}

else

{

lb2 =new Label("");

}

bufferInnePanel.add(lb2);

l3 =new Label("Product 3");

bufferInnePanel.add(l3);

if (buffLength>2)

{

lb3 =new Label(bufferList.getObjectByIndex(2).present_me());

lb3.setForeground(

bufferList.getObjectByIndex(2).getProducer().getProducerColor());

}

else

{

lb3 =new Label("");

}

bufferInnePanel.add(lb3);

l4 =new Label("Product 4");

bufferInnePanel.add(l4);

if (buffLength>3)

{

lb4 =new Label(bufferList.getObjectByIndex(3).present_me());

lb4.setForeground(

bufferList.getObjectByIndex(3).getProducer().getProducerColor());

}

else

{

lb4 =new Label("");

}

bufferInnePanel.add(lb4);

bufferInnePanel.setBorder(BorderFactory.createLineBorder(Color.MAGENTA));

WhiteRectangel rect1=new WhiteRectangel();

WhiteRectangel rect2=new WhiteRectangel();

bufferStorInnePanel.add(rect1);

bufferStorInnePanel.add(bufferInnePanel);

bufferStorInnePanel.add(rect2);

bufferPanel.add(bufferStorInnePanel);

return bufferPanel;

}

publicvoid addFrame(SpelFrame fr)

{

this.frame=fr;

}

}

Message was edited by:

_Jasper_

[31405 byte] By [_Jasper_a] at [2007-10-3 4:28:40]
# 1

Umm yes. This is too much code.

> Threads are not exactly my cup of tea. All I want to

> do is to make the application pause as long as the

> time printed from the keyboard.

>

What do you mean printed from they keyboard?

There are several ways to make a thread wait. You could wait a set of time with sleep. You can have a thread block with wait/notify.

Can you post a short description and maybe 10 lines of code with some specifics?

cotton.ma at 2007-7-14 22:31:40 > top of Java-index,Java Essentials,Java Programming...
# 2
For some reason I can't edit the post (shorten it).This is not work or something I get payed for. Something I have to do and also would like to learn (with your help). But right now I don't like threads :)I'll get back to you with a shorter and more consice
_Jasper_a at 2007-7-14 22:31:40 > top of Java-index,Java Essentials,Java Programming...
# 3

> For some reason I can't edit the post (shorten it).

>

Because it was replied to already. Once some replies to a post it is locked for editing.

> This is not work or something I get payed for.

> Something I have to do and also would like to learn

> (with your help). But right now I don't like threads

> :)

>

Just ignore dizzy until such time that she posts something constructive and not just commentary about how she feels about you personally.

At any rate the answer is in my first reply

"There are several ways to make a thread wait. You could wait a set of time with sleep. You can have a thread block with wait/notify."

You may find this helpful

http://java.sun.com/docs/books/tutorial/essential/concurrency/index.html

> I'll get back to you with a shorter and more consice

> version.

Okay well good luck. If you do I'll try and give you more specifics. As I said though the answer is above and that threading tutorial will probably help you quite a bit.

cotton.ma at 2007-7-14 22:31:40 > top of Java-index,Java Essentials,Java Programming...
# 4

Here's the problem (I think).

The setTime method should return the number of seconds(?) that sets sleep-time for the put and take methods.

This is for putting objects in, the consumer has a simular thing for take.

public class Producer extends Location

implements Runnable

public void run()

{

while(!Thread.interrupted())

{

try

{

Thread.sleep(tid);

Product produkt= produce();

this.buffer.put(produkt);

}

catch(InterruptedException avbruten)

{

break;

}

}

}

public class ProductList implements Runnable {

private ArrayList<Product> products = new ArrayList<Product>();

public void run() {}

public void setProduct(Product product)

{

this.products.add(product);

--

public synchronized void put(Product product)

{

while (this.bufferList.getListLength()>=4)

while (bufferList.isEmty())

try {Thread.sleep(SpelFrame.setTime(tid));}

catch (InterruptedException e)

{

return;

}

--

simulateBuffering.addActionListener(this);

setVisible(true);

setDefaultCloseOperation(EXIT_ON_CLOSE);

}

public void actionPerformed(ActionEvent e) {

Scanner sc = new Scanner((simulateBuffering.getText()));

long temp = (sc.nextLong());

setTime(temp);

}

public static long setTime(long a){

long tid = a;

return tid;

}

}

_Jasper_a at 2007-7-14 22:31:40 > top of Java-index,Java Essentials,Java Programming...
# 5

This code makes me worry

public static long setTime(long a){

long tid = a;

return tid;

}

Usually when you have a set method it doesn't return anything. And you

aren't returning anything of value there either.

Why is that method not just blocking? I assume your question is how do

I determine how long X will take at run time.

Well that's not important if as it seems earlier in your code you don't

ant anything to happen till X is done. So instead of sleeping just wait

for X to finish. And problem solved without having to calculate how much

time X will take.

cotton.ma at 2007-7-14 22:31:40 > top of Java-index,Java Essentials,Java Programming...
# 6

My native language is not english so I'm not sure what you mean by

> Why is that method not just blocking?

The requirements say that when a consumer or a producer accesses the buffer, it should be delayed with a value (seconds) set from the GUI.

Right after access to the buffer, the producing and consuming should also be delayed the same way simulating producing / consuming time. Only one thread at the same time should access the buffer.

_Jasper_a at 2007-7-14 22:31:40 > top of Java-index,Java Essentials,Java Programming...
# 7

Even your first long code won't compile let alone run.

For analyzing producer-consumer code, the most important part we should see is the driver part, or app main part which might have main() method and should do some queueing/dequeueing.

Delaying part should be trivial, I think.

Post a small demo code that is generally compilable, runnable and could reproduce your problem. See: http://homepage1.nifty.com/algafield/sscce.html

hiwaa at 2007-7-14 22:31:40 > top of Java-index,Java Essentials,Java Programming...
# 8

Ok, I tried to remove some code according to the sscce page, but then nothing worked as a runnable version. The problem is both GUI and threads (the simulate buffer/produce/consume time is set from the GUI). So I gave it up, were to many things coupled :(

When I become a better java programmer I will follow that convention for sure.

I did however put all the files in a directory if someone has the courage to look at my horrible GUI ;)

http://www.angelfire.com/planet/jaasper/links_javaprojekt.html

Thank you for your help so far!

_Jasper_a at 2007-7-14 22:31:40 > top of Java-index,Java Essentials,Java Programming...
# 9

If I change the setTime method, the buffer class doesn't work.

public long tid;

public long setTime(long a){

tid = a;

}

public synchronized void put(Product product)

{

while (this.bufferList.getListLength()>=4)

while (bufferList.isEmty())

try {Thread.sleep(SpelFrame.setTime(tid));}

catch (InterruptedException e)

{

return;

The error message is shown on SpelFrame.setTime(tid) above at try.

Cannot make a static reference to the non-static method setTime(long) from the type SpelFrame

_Jasper_a at 2007-7-14 22:31:41 > top of Java-index,Java Essentials,Java Programming...
# 10

I don't need to fall at your feet

Just 'cause you cut me to the bone

And I won't miss the way that you kiss me

We were never carved in stone

If I don't listen to the talk of the town

Then maybe I can fool myself..

I'll get over you.. I know I will

I'll pretend my ship's not sinking

And I'll tell myself I'm over you

'cause I'm the king of wishful thinking

I am the king of wishful thinking

Googe "Java Monitors Synchronized"

filestreama at 2007-7-14 22:31:41 > top of Java-index,Java Essentials,Java Programming...
# 11
The setTime() does not return a long. Please check the function signature
smdattaa at 2007-7-14 22:31:41 > top of Java-index,Java Essentials,Java Programming...
# 12

> The setTime() does not return a long. Please check

> the function signature

Yepp. And also, I wonder why everyone thinks they're the first to encounter a specific error message.

http://onesearch.sun.com/search/onesearch/index.jsp?qt=Cannot+make+a+static+reference+to+the+non-static+method+&subCat=siteforumid%3Ajava31&site=dev&dftab=siteforumid%3Ajava31&chooseCat=javaall&col=developer-forums

CeciNEstPasUnProgrammeura at 2007-7-14 22:31:41 > top of Java-index,Java Essentials,Java Programming...
# 13
Thank you smdatta, I'll look in to that.
_Jasper_a at 2007-7-14 22:31:41 > top of Java-index,Java Essentials,Java Programming...
# 14
I would like to renew my concerns for this approach at this time. It is worse than pointless to force multithreaded code to behave as if it were single threaded.
cotton.ma at 2007-7-14 22:31:41 > top of Java-index,Java Essentials,Java Programming...
# 15
Ok, do I treat them as single threaded?
_Jasper_a at 2007-7-21 10:32:13 > top of Java-index,Java Essentials,Java Programming...
# 16

> Ok, do I treat them as single threaded?

From what I can tell yes.

Here is an analogy I hope will be helpful to you.

Two people (threads) are blowing up (inflating) balloons.

Person 1 blows up the balloon.

Person 2 ties the balloon off.

Is this multithreaded? Well no not really. There are two threads involved

but the execution is not parallel.

The following is multithreaded.

Person 1 blows up balloon and ties it off.

Person 2 blows up baloon and ties it off.

Now that is multithreaded.

And back to your point it seems to me, using my analogy that you are

trying to make person 2 wait to tie off the balloon until person 1 is

finished blowing it up. And I ask why. Why because if you have a setup

like that it's not really multithreaded at all. But a single thread disguised

as multiple.

Now let's say I have 6 people (threads) to blow up the balloons and I

have discovered that it takes twice as long to blow them up as it does to

tie them off. How can I effectively multithread this?

Like so.

4 people blow up balloons. When the balloons are inflated they stand

in a line waiting for the tie people to come.

2 people are tieing them off. When they see someone in line they get

the balloon and tie it. When they are finished they go back to the line to

grab the next one. If there is nobody in line they wait until there is one.

***************

Generally speaking using sleep to control threading logic is wrong. It's

better to use wait and notify and some sort of queue if needed. And if

that's all too much then I would reconsider the multiple threads at all.

cotton.ma at 2007-7-21 10:32:13 > top of Java-index,Java Essentials,Java Programming...
# 17

Dont let the threads get you down :)

I have a simple producer - consumer program that may help you, if you are interested contact me throught my e-mail andreasmic@gmail.com.

And you are right GUI is also a problem when multithreading , since most swings components are not thread safe and the ones that are, are marked in the API.

When update swing components from multiple threads you should use:

SwingUtilities.invokeLater(Runnable)

EventQueue.invokeLater(Runnable)

Hope i've been of some assistance!

Andreas.CYa at 2007-7-21 10:32:13 > top of Java-index,Java Essentials,Java Programming...