Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
geeves
Sep 16, 2004

Not a specific code question

When are the best times to synchronize? It seems like the logical choice is for when transactions occur (adding / modifying database or repository).

But are there other times when synchronization becomes crucial? Or should it be kept to the minimum?

Adbot
ADBOT LOVES YOU

HFX
Nov 29, 2004

geeves posted:

Not a specific code question

When are the best times to synchronize? It seems like the logical choice is for when transactions occur (adding / modifying database or repository).

But are there other times when synchronization becomes crucial? Or should it be kept to the minimum?

If you are modifying a database or repository it is better to let the transaction engine of the database to do the work of synchronizing. Synchronizing mostly becomes an issue when one thread needs to pass or modify data that another thread can use. You try to keep it to a minimum by only locking what's absolutely needed.

yatagan
Aug 31, 2009

by Ozma

geeves posted:

Not a specific code question

When are the best times to synchronize? It seems like the logical choice is for when transactions occur (adding / modifying database or repository).

But are there other times when synchronization becomes crucial? Or should it be kept to the minimum?

This is a very complex question, one that could easily span a graduate level course. Start reading up, I like the book "Java Concurrency in Practice".

Fly
Nov 3, 2002

moral compass

geeves posted:

Not a specific code question

When are the best times to synchronize? It seems like the logical choice is for when transactions occur (adding / modifying database or repository).

But are there other times when synchronization becomes crucial? Or should it be kept to the minimum?
You need to synchronize whenever you modify the representation of an object in a non-atomic way if that object can be accessed by other threads.

The synchronization locking must not be more fine-grained than the represented data.

code:
// Representation invariant: balance cannot be negative
private BigDecimal balance;

public synchronized void deposit(BigDecimal amt)
{
    balance = balance.add(amt);
}

public synchronized void withdraw(BigDecimal amt)
{
    BigDecimal after = balance.subtract(amt);
    if (after.signum() >= 0) {
        balance = after;
    }
    else {
        throw new OverdraftException(after);
    }
}

public BigDecimal getBalance()
{
    return balance;
}
The deposit and withdraw methods must be synchronized at least on the balance object. I am synchronizing on the containing object for simplicity. If we did not synchronize, then two threads modifying the object via any combination of deposit() and withdraw() could invalidate the representation (i.e., the value of balance).

The getBalance() method does not cause any change to the value of balance, and because the object assignment that occurs in deposit() and withdraw() is atomic, getBalance() does not need to be synchronized.

The race condition that could invalidate the balance occurs because in deposit() and withdraw() we are both checking or getting the value of balance before using it to calculate the new balance. If one thread is processing the bytecodes for deposit() or withdraw(), and another thread is doing the same simultaneously owing to thread preemption or parallel processing, the values on the stack for balance that the first thread sees would be wrong, and the resulting value would be wrong.

E.g.,

It can work sometimes if the sequence of operations performed by the JVM is "just right" resulting in the correct value of $16 for balance:
  1. The balance starts at $4.
  2. Thread 1 calls deposit($5).
  3. Thread 2 calls deposit($6).
  4. Thread 1 reads a value of $4 for balance.
  5. Thread 1 adds $5 to $4 to yield a new value of $9.
  6. Thread 1 assigns $9 to balance.
  7. Thread 2 reads a value of $9 for balance.
  8. Thread 2 adds $6 to $9 to yield a new value of $16.
  9. Thread 2 assigns $16 to balance.
However, because the operations of Thread 1 and Thread 2 could be interleaved in any possible way so long as the operations of Thread 1 maintain their overall order, and the operations of Thread 2 maintain their overall order, the JVM could process them like this resulting in a wrong value of $10 in balance:
  1. The balance starts at $4.
  2. Thread 1 calls deposit($5).
  3. Thread 2 calls deposit($6).
  4. Thread 1 reads a value of $4 for balance.
  5. Thread 2 reads a value of $4 for balance.
  6. Thread 2 adds $6 to $4 to yield a new value of $10.
  7. Thread 1 adds $5 to $4 to yield a new value of $9.
  8. Thread 1 assigns $9 to balance.
  9. Thread 2 assigns $10 to balance.
You could interleave the thread operations in other ways to generate other incorrect values, and you could call the withdraw() method as well to make it more complicated. The getBalance() method does not really care which version of balance it sees only because my example never assigns an intermediate value to balance. If I wrote the withdraw() method as follows, then getBalance() would also need to be syncrhonized:
code:
public synchronized void withdraw(BigDecimal amt)
{
    balance = balance.subtract(amt); // Assigning an possibly invalid value!
    if (balance.signum() < 0) {
        // getBalance() called now returns an invalid value.
        balance = balance.add(amt); // Change the value back.
        throw new OverdraftException(balance.subtract(amt));
    }
}
Calling an unsynchronized getBalance() can return an intermediate value that never represented a real value of balance because it may violate the representation invariant of never being negative. Code using this class should be able to depend on the representation invariant, so it might fail in unexpected or unnoticed ways.

This example assumes that all of the values are stored on the JVM stack and read from a single copy of the data in the JVM's memory, but the JVM memory model also allows each thread to have its own copy of parts of memory, so it gets even worse unless you syncrhonize. In addition to getting a lock on an object, synchronization causes the thread to flush its own copy of memory and read from the "real" memory.

edit: spelling and grammar

Fly fucked around with this message at 17:26 on Jan 15, 2010

maskenfreiheit
Dec 30, 2004
...

maskenfreiheit fucked around with this message at 03:44 on Sep 29, 2010

covener
Jan 10, 2004

You know, for kids!

GregNorc posted:


float x;
x = -123.987;

literals like this are doubles by default, unless you append an 'f' as in -123.987f.

mister_gosh
May 24, 2002

Is there a design patterns megathread?

epswing
Nov 4, 2003

Soiled Meat

mister_gosh posted:

Is there a design patterns megathread?

You tell me. http://forums.somethingawful.com/f/search

8ender
Sep 24, 2003

clown is watching you sleep
This is a strangely specific JSTL question. I'm using forEach to loop through some data that looks like this

Program 1 | Homeless Shelter
Program 2 | Homeless Shelter
Program 3 | Soup Kitchen
Program 4 | Soup Kitchen

Right now I want to write a header whenever the program type (second column) changes. To do this I'm creating a temporary variable, populating it with the program type of the current row at the end of the loop, and then I have some logic at the start of the loop that compares the program type of the current row and the temporary variable and throws up a header when its different.

I feel like there is a better way to do this but I'm coming up short searching around. Any ideas?

8ender
Sep 24, 2003

clown is watching you sleep
Never mind, got it with this little line. Friday afternoon coding :(
code:
 <c:if test="${site.programList[progRow.index].programTypeCode != site.programList[progRow.index-1].programTypeCode}">

Malfeasible
Sep 10, 2005

The sworn enemy of Florin

GregNorc posted:

So I have this really simple code I need to run. There seems to be a syntax issue with the negative number, but I'm not sure how to write it... do I put it in quotes or something?

code:
import java.text.DecimalFormat;

/** 
This program demonstrates the DecimalFormat class 
*/

public class Format4
{
	public static void main(String[] args)
	{
		float x; 
		x = -123.987;
		// Create a DecimalFormat object
		DecimalFormat formatter = new DecimalFormat("%10.1f");

		//display the four variable's contents
		System.out.println(formatter.format(x));
	}
}
Here's the error I get:


I'm very new to java, and extremely confused... I thought I just specified that x is a float? Why would the compiler tell me to make it a float if I just set it to float?

In Java you have to put an 'f' after float values.
So change the line where you assign x to :
code:
x = -123.987f;
Also, are you sure about the format "%10.1f" ? What do you want the output to look like?

CoasterMaster
Aug 13, 2003

The Emperor of the Rides


Nap Ghost
Is there a way to listen for keyboard events in a console app? It's fairly easy when using KeyListeners, but it looks like I can only use them on GUI apps.

PT6A
Jan 5, 2006

Public school teachers are callous dictators who won't lift a finger to stop children from peeing in my plane

CoasterMaster posted:

Is there a way to listen for keyboard events in a console app? It's fairly easy when using KeyListeners, but it looks like I can only use them on GUI apps.

I'm not sure of anything Java-specific, but to do that in other languages, you'd use some sort of terminal control library like (n)curses. A quick google search suggests that there is a Java curses library, so you could try that.

Max Facetime
Apr 18, 2009

I guess you could read directly from the console input by doing System.setIn(yourInputStream);

lewi
Sep 3, 2006
King
Can anyone tell me why this:
code:
public class Board {

    char[][] board;

    public Board(){
        board = new char[9][13];
    }

    public void fillBoard(String s){
        if(s.length() != 117){
            System.out.println("Invalid board");
            System.exit(0);}

        for(int i=0; i<9; i++){
            this.board[i] = s.substring(i*13,(i+1)*13).toCharArray();}
    }

    public void printBoard(){
        String s = "";
        for(int i=0; i<9; i++){
            s = s+this.board[i];}
        System.out.println(s);
    }

    public static void main(String[] args){
        Board b = new Board();
        b.fillBoard(a 117 length string that isn't reproduced so as to not break tables);
        b.printBoard();
    }
}
is printing:
[C@3e25a5[C@19821f[C@addbf1[C@42e816[C@9304b1[C@190d11[C@a90653[C@de6ced[C@c17164
as the output?

The intent of the code ought to be clear - .fillBoard takes a 117 character length string and populates it into the 9x13 board. .printBoard takes the board and should print out a string that it makes...

lewi fucked around with this message at 01:39 on Jan 26, 2010

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
Java is not C. toString() on a char array in Java works exactly like toString() on any other array type: it produces some internal information about the array reference. You probably want to just use Strings.

Internet Janitor
May 17, 2008

"That isn't the appropriate trash receptacle."
Lewi: If you want to print out a nicely formatted version of a primitive array, use Arrays.toString(foo).

lewi
Sep 3, 2006
King

rjmccall posted:

Java is not C. toString() on a char array in Java works exactly like toString() on any other array type: it produces some internal information about the array reference. You probably want to just use Strings.

I was working from this bit from the java String documentation:

http://java.sun.com/j2se/1.4.2/docs/api/java/lang/String.html posted:

Strings are constant; their values cannot be changed after they are created. String buffers support mutable strings. Because String objects are immutable they can be shared. For example:

String str = "abc";


is equivalent to:

char data[] = {'a', 'b', 'c'};
String str = new String(data);

This seems to imply that you can cast a char array to a string...

Internet Janitor posted:

Lewi: If you want to print out a nicely formatted version of a primitive array, use Arrays.toString(foo).
That's the thing - I don't want the formatted version, I just want it to come out as it went in. Actually, ultimately it's irrelavent to this project because it won't be printing anything but it's nice to know that it's possible using simple code.

lewi fucked around with this message at 00:27 on Jan 25, 2010

Internet Janitor
May 17, 2008

"That isn't the appropriate trash receptacle."

lewi posted:

This seems to imply that you can cast a char array to a string...

There's a big difference between creating an object from a character array and casting the array itself to an instance of that object. As rjmccall said, Java is not C- object instances should not be thought of as structs.

Also note that the Javadocs for String(char[]) indicate that the source array is copied. If it was possible to create a string backed by a character array that could then be modified and reflected in the associated string, it wouldn't be immutable.

lewi
Sep 3, 2006
King
I'm obviously not as awake as I thought I was - I was misunderstanding the difference between String(char[]) and toString(). drat.
Thanks for your help guys.

maskenfreiheit
Dec 30, 2004
...

maskenfreiheit fucked around with this message at 03:39 on Sep 29, 2010

LakeMalcom
Jul 3, 2000

It's raining on prom night.
One thing that jumps out at me is that all of your if.. blocks are not wrapped in curly braces: {}.

In Java, it is syntactically OK to have an if.. block with no braces, but that means only the next line is part of the if.. block.

lamentable dustman
Apr 13, 2007

🏆🏆🏆

look here for the error:

code:
// now that we have verified the input, we can move onto the main program logic
int answer = posInt / base;
while (answer > base)
{
	answer = posInt / base;
}
still won't spit out the right answer but you should be able to figure it out

e: yea, forgot to mention that, your style is horrible. Stay way from bracket-less statements

lamentable dustman fucked around with this message at 17:28 on Jan 25, 2010

Mustach
Mar 2, 2003

In this long line, there's been some real strange genes. You've got 'em all, with some extras thrown in.

GregNorc posted:

Our professor just tells us to talk to the TA if we have questions, and our TA deducts points if we ask her questions about the lab, so I'm not really sure where to turn.
Turn to your professor with evidence that your TA is screwing you.

maskenfreiheit
Dec 30, 2004
...

maskenfreiheit fucked around with this message at 03:44 on Sep 29, 2010

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
The problem has nothing to do with variable scope.

I will advise you the same way I advise every intro student: stop abstractly reasoning about your code. Don't get me wrong abstract reasoning is a very important skill! but it's easy to blind yourself to bugs, thinking that the code is doing what you want instead of what you've written.

It's very simple. Get out a piece of paper. Pretend you're the computer. Whenever a variable comes into scope, write down the name of the variable and its current value. Whenever you assign to a variable, cross out the old value and write down the new value. Don't skip steps; just follow the program, line by line, expression by expression, and I guarantee that you will find your bug.

lamentable dustman
Apr 13, 2007

🏆🏆🏆

GregNorc posted:

OK so I'm guessing it's something relating to scope? (I was getting 4 for the first test sin ce 45/10 = 4.5 and since the result is an int, it gets truncated to 4, hence the appearance it was working?)

I'm still completely stumped - if I put the answer variable inside the while statement, then I have nothing to test for.

(I tried using a counter, but I always got a value of zero but I'm pretty sure that's not how it should be done anyways)

Edit: But if that's as much help as you can give without telling me the answer, that's ok, I'll risk the crazy TA... I want to try and figure this out on my own if possible.

You are thinking to far ahead. Focus on one error at a time. In the iteration of the code you posted the biggest error in the code is the infinite loop that is causing the "hanging."

Follow the debugging steps rjmccall posted and remember to take things one at a time. Using sys outs or a debugger to pinpoint your problems couldn't hurt either.

epswing
Nov 4, 2003

Soiled Meat

Mustach posted:

GregNorc posted:

Our professor just tells us to talk to the TA if we have questions, and our TA deducts points if we ask her questions about the lab, so I'm not really sure where to turn.

Turn to your professor with evidence that your TA is screwing you.

Seconding this. That's majorly hosed. You should be encouraged to ask as many questions as necessary to understand the lesson/exercise.

mister_gosh
May 24, 2002

I'm being told that my code is crap unless I'm implementing design patterns that promote an efficient design. I'm self taught and have only had the opportunity to have one "mentor" (1 year) for the past ten year career (and that was in Perl). Most of the code I've needed to manage was small projects and thus wrapping my head around some efficient reusable designs is a little tough.

I have a "node" object that I would like to represent on the client side, middleware or in a UI as a Data Transfer Object/Value Object.

I have the potential here for both the facade and/or the factory patterns to manage the various types of "node" objects, let's call them StandardNode, ComplexNode1 and ComplexNode2.

The client side should request the DTO and then I imagine a DAO class will take care of the dirty work of getting the necessary information through a proprietary API, executing the appropriate setters on the DTO and then handing that DTO back to the client side.

The client side could then access that DTO for information or fire off more requests to the factory to get the nodes next child or some other entirely different node.

I'm really not sure how to implement this. I figure the facade is possible here because it would hide the potential complexities of the different node types from the uncaring client, but then the factory is also possible here because it could manage the creation better of the DTO. I'm just lost and could either use some pseudo code to help paint a clearer picture, or at the very least be pointed in the direction of a definitive (online) source, outside of the GoF, that would help me quickly get up to speed.

FateFree
Nov 14, 2003

Question about generics and inheritance. I have a domain model hierarchy like so:

Persistable > Address

Persistable as a parent has fields that all persistable objects have, like id, timeCreated, timeModified.

Address is a subclass which has properties such as address, city, state, yada yada.

I have a Dao class which allows for dynamic where clauses. Traditionally, I just used static strings to identify columns, like so:

code:
Persistable {
 public static String ID = "id";
 public static String TIME_CREATED = "time_created";
}

Address extends Persistable {
  public static String CITY= "city";
}
Recently we upgraded to Java 1.5, so I wanted to add type safety. At first I looked into enums for these fields, but I didn't like the fact that I couldn't extend the enums of the Persistable class. So instead, I created (rjmccall's) Property<T, V> class, where T is the type of the class, and V is the type of the value. Now the hierarchy looks like this:

code:
Persistable {
 public static Property<Persistable, Long> ID = ...; // instantiate
 public static Property<Persistable, Long> TIME_CREATED = ...;  // instantiate
}

Address extends Persistable {
  public static Property<Address, String> CITY = "city";
}
This enables the Dao to have some type safety. For example, if I want to search by id or address, i would do this:

code:
PersistableDao<T extends Persistable> {

 public List<T> find(Property<T, V> property, V value);

}
PersistableDao<Address> addressDao = ...; // instantiate
addressDao.find(Address.ID, 1L);
addressDao.find(Address.CITY, "new york");
With the type safety in place, the addressDao will throw a compile error if the value type passed in doesn't match the type of V, which is great. The problem is, this code doesn't compile. The first find errors because the static ID property was defined with a type of Persistable instead of the more specific Address. I thought since Address extends Persistable, it would still work. But unfortunately it doesnt. The only way to make it compile was to move the static ID into the Address class like this:

code:
Address extends Persistable {
  public static Property<Address, Long> ID = ...; // instantiate
  public static Property<Address, String> CITY = "city";
}
But now I'm stuck in the same way, I cant use inheritance on these properties anymore. Does anyone have any idea how I can make this work while maintaining the inheritance of my common Properties? Its almost like I need for the find method to accept T OR a parent of T.

FateFree fucked around with this message at 00:21 on Jan 26, 2010

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

FateFree posted:

Recently we upgraded to Java 1.5, so I wanted to add type safety. At first I looked into enums for these fields, but I didn't like the fact that I couldn't extend the enums of the Persistable class. So instead, I created a Property<T, V> class, where T is the type of the class, and V is the type of the value.

An excellent idea! Surely your work is touched with genius.

FateFree posted:

Does anyone have any idea how I can make this work while maintaining the inheritance of my common Properties? Its almost like I need for the find method to accept T OR a parent of T.

If only this had been a crucial component of the original idea! It is unfortunate you were unable to consult these fora previously.

code:
public <V> List<T> find(Property<? super T, V> property, V value);

rjmccall fucked around with this message at 23:52 on Jan 25, 2010

FateFree
Nov 14, 2003

rjmccall posted:

An excellent idea! Surely your work is touched with genius.

code:
public <V> List<T> find(Property<? super T, V> property, V value);

Well thanks, I tried to use the super property but apparently I wasn't using it correctly. Your way solved my problem.

Was there something wrong with my original Property<T, V> idea in general for the sarcastic genius remark?

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

FateFree posted:

Was there something wrong with my original Property<T, V> idea in general for the sarcastic genius remark?

Nope; it's just that it's pretty much exactly what I told you to do twenty days ago when you asked this question then.

FateFree
Nov 14, 2003

rjmccall posted:

Nope; it's just that it's pretty much exactly what I told you to do twenty days ago when you asked this question then.

At touche salesman. I editted my last question, since I asked on a couple forums I didn't remember that I asked here. But works great now, thank you.

maskenfreiheit
Dec 30, 2004
Edit: Double Post

maskenfreiheit fucked around with this message at 21:31 on Mar 13, 2017

mister_gosh
May 24, 2002

How do I use a Singleton on a subclass of a abstract class?

NewConnection.java
code:
public class NewConnection extends Connection {

   private static NewConnection uniqueInstance;
    
   public static synchronized NewConnection getInstance(...) {
      if(uniqueInstance == null) {
         uniqueInstance = new NewConnection(...);
      }
      return uniqueInstance;
   }
}
Connection.java
code:
public abstract class Connection {
    
    private static Connection uniqueInstance;
    public abstract Connection getInstance() throws ConnectionException;

}
Test.java
code:
Connection connection = null;
connection.getInstance();

Janitor Prime
Jan 22, 2004

PC LOAD LETTER

What da fuck does that mean

Fun Shoe
code:
Connection connection = NewConnection.getInstance();

mister_gosh
May 24, 2002

MEAT TREAT posted:

code:
Connection connection = NewConnection.getInstance();

Thanks! I should have been more specific though.

Test.java does not necessarily know which Connection class was used. I suppose I could set a property somewhere in the application which defines the connection type, and then execute a case switch, if/else scheme.

code:
Connection connection = null;
String connectionType = foo.getConnectionType();
if(connectionType.equalsIgnoreCase("")) {
   connection = NewConnection.getInstance();
} else {
   connection = StandardConnection.getInstance();
}
I could do this, but it seems like bad design.

RitualConfuser
Apr 22, 2008

mister_gosh posted:

I could do this, but it seems like bad design.

You could move that to a method in some connection factory or whatever. So, something along the lines of:

code:
public static Connection getConnection(String connectionType) 
throws ConnectionException {
    if(connectionType.equalsIgnoreCase("")) {
        return NewConnection.getInstance();
    } else {
        return StandardConnection.getInstance();
    }
}
Not sure what the point of having getInstance in Connection is though since you can't change getInstance to static in the child classes.

RitualConfuser fucked around with this message at 05:29 on Jan 27, 2010

Adbot
ADBOT LOVES YOU

1337JiveTurkey
Feb 17, 2005

This code is under the presumption that you're looking for there to be many possible implementations of the abstract class but want only one at runtime. Using System.getProperty() isn't necessary but fits with established practice in the libraries. In order to make this work, you'll also need to make sure that you've got a META-INF/services directory in the JAR file with the children of the Connection class listed.

code:
public static synchronized Connection getInstance() throws ConnectionException {
	if (uniqueInstance != null)
		return uniqueInstance;
	String connectionType = System.getProperty("Connection.Type");
	for (Connection connection : ServiceLoader.load(Connection.class)) {
		if (connectionType.equals(connection.getConnectionType()) {
			uniqueInstance = connection;
			return uniqueInstance;
		}
	}
	throw new IllegalStateException("No Connection has type " + connectionType);
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply