Bill Nelsen

Greenhorn
+ Follow
since Aug 11, 2004
Cows and Likes
Cows
Total received
0
In last 30 days
0
Total given
0
Likes
Total received
0
Received in last 30 days
0
Total given
0
Given in last 30 days
0
Forums and Threads
Scavenger Hunt
expand Ranch Hand Scavenger Hunt
expand Greenhorn Scavenger Hunt

Recent posts by Bill Nelsen

I have frequently been asked for code samples and I have always asked for it when I've been performing an interview.

You can tell a lot about a candidate from reading through their code sample. In particular, we're looking for someone that has a strong working methodology and commenting style. I would much rather hire a less talented programmer than works in a thorough manner, than a more talented programmer that is sloppy.

12 years ago
Noticed one error. Made a change to the following method:

public void read_withlock(String name) {
logger.debug("read_withlock=" + name);

while (writing == true) {
synchronized (this) {
try {
wait();
logger.debug("AWOKE from wait");
} catch (InterruptedException e) {
logger.debug("interrupted write_withlock");
}
}
}
readFromFile(name);
}
As a learning exercise, I am trying to implement a scenario where multiple readers are allowed to read a file, but only one writer is allowed to write. As a consequence, no one can read during a write operation. I think that this is the classic MROW problem.

I was looking for the simplest solution. I had hoped that I was on the right track, but it appears that I am missing something. Because I am not seeing any AWOKE messages from the wait() method. So if I am on the wrong track and there is a simpler approach, please let me know.

public class File_locks {
public static String fname = new String("C:/Temp/file.txt");

static public void main(String arg[]) {
Logger logger = Logger.getLogger("file_locks");

// Create a text.file
try {
File file = new File("filename");

// Create file if it does not exist
boolean success = file.createNewFile();
if (success) {
// File did not exist and was created
logger.debug("File did not exist and was created");
} else {
//File already exists
logger.debug("File already exists");
}
} catch (IOException e) {
logger.debug("Can't create new file");
e.printStackTrace();
System.exit(-1);
}

// Ensure that there is enough readers and writers to
// cause conflicts
for (int i = 0; i < 10; i++) {
new ModeThreads("writer" + i).start();
new ModeThreads("reader" + i).start();
}
}
}

class ModeThreads extends Thread {

private static BufferedReader in;
private static BufferedWriter out;
public static String fname = new String("C:/Temp/file.txt");
public static boolean writing = false;
Logger logger = Logger.getLogger("file_locks");

ModeThreads(String name) {
super(name); // Save thread's name
}

public void run() {

while (true) {
if (Thread.currentThread().getName().startsWith("reader")) {
read_withlock(Thread.currentThread().getName());
}
if (Thread.currentThread().getName().startsWith("writer")) {
write_withlock(Thread.currentThread().getName());
}
}
}

// Requirements: Support a multiple number of readers. This precludes simply synchronizing the method
// .
public void read_withlock(String name) {
logger.debug("read_withlock=" + name);

// If a write operation is currently occuring, then wait
// until it is completed
if (writing) {
synchronized (this) {
try {
wait();
logger.debug("AWOKE from wait");
} catch (InterruptedException e) {
logger.debug("interrupted write_withlock");
}
}
}
readFromFile(name);
}

// This works fine, because it supports a single writer
public synchronized void write_withlock(String name) {
logger.debug("read_withlock=" + name);

// It seems that the writing flag needs to be within the critical area, otherwise we could set
// the writing flag, but not get access to the lock
synchronized (this) {
writing = true;
writeToFile(name);
writing = false; // Does this need to come before or after the notify
notify();
}
}

private String readFromFile(String name) {
logger.debug("readFromFile: " + name);
String s = null;
try {
in = new BufferedReader(new FileReader(fname));
s = in.readLine();
logger.debug("readFromFile: " + s);
in.close();
} catch (FileNotFoundException e) {
System.err.println("Could not open " + fname + " for reading");
System.exit(-1);
} catch (Exception e) {
// All other exceptions must close the file
try {
in.close();
} catch (IOException e2) {
System.err.println("in.close() unsuccessful");
}
}
return s;
}

private void writeToFile(String name) {
logger.debug("writeToFile: " + name);

try {
PrintWriter out = new PrintWriter(new BufferedWriter(
new FileWriter(fname)));
out.println(name);
out.close();
} catch (FileNotFoundException e) {
System.err.println("Could not open " + fname);
System.exit(-1);
} catch (Exception e) {
try {
in.close();
} catch (IOException e2) {
System.err.println("in.close() unsuccessful");
System.exit(-1);
}
}
}

}
You might to also take a look at Jeffrey Friedl's "Mastering Regular Expressions" book. He provides lots of examples for regex optimizations, to limit the number of different combinations that the generated regular expression has to check. Since these regular expressions are being run so many times, it seems that even a small optimization could potentially result in a significant performance increase.
16 years ago
This one has really thrown me for a loop:


Try working it out first, before looking at the answer below:



Answer:
Mobile.showDevice,null Mobile.showDevice,Mobile.device Mobile.showDevice,Mobile.device

My questions:
1. Why isn't (what at least appears to be) the Phone constructor called?
2. why isn't the device available during the Mobile constructor??
[ January 24, 2005: Message edited by: Mark Spritzler ]
I don't quite understand the answer to this question:

This code produces repeated output of 100. The question is why doesn't it display any values of 200. The answer states that although bContinue does get set to true, the setPrice call is blocked because setPrice and run are both synchronized.

I think that I am still missing something here. Are the setPrice and run methods somehow tied together?? So since the run method is locked, then the setPrice method is also locked??

Why is

(Please use tags around formatted Java code)
[ January 24, 2005: Message edited by: Barry Gaunt ]
I am looking for a comprehensive online Javascript reference for the specification of the language.
In the following code:


class A {void m1() {System.out.print("A.m1");}}

class B extends A {
static void m1(String s) {System.out.println(s+",");}
}

class D {
static class E {
static void m1() { System.out.println("E"); };
}
}

class C {
public static void main (String[] args) {
B.m1("main"); // 1
new D.E().m1(); // 2
}
}

This code compiles correctly, but why does line 2 require a "new" keyword, while line 1 doesn't. Removing the "new" keyword on line 2 results in a
C.java:17: cannot resolve symbol
symbol : method E ()
location: class D
D.E().m1();

In both instances, we are dealing only with static entities. So why do static classes need to be instantiatated??
Thanks for the link to a great article. I am reading all 3 parts of the article.
I started to play around with nested interfaces, because I read that by definition they are static. So this is the trivial example that I arrived at,

interface A {
interface B {
void help();
}
}
class Base implements A.B {
public void help() { System.out.println("Help"); }
}

class Test {
static public void main(String[] args) {
A.B b = new Base();
b.help();
}
}

Since the nested interface is static, it requires this unusual notation (or at least I think that it does). I have a difficult time intuitively picturing what a static interface would look like. Is there a good use for a nested interface or is it just a feature (like interfaces that contain concrete classes), which is just there for completeness, but doesn't really serve a useful purpose??
~
Thanks for your very informative reply, Mike.

I think that I understand things now. The counter case that I presented earlier involved the overriding of methods, in addition to the overloading of methods, so it was an entirely different situtation.

This was a very good problem for me, because it clearly illuminated several subtle areas in Java for me.
Mike, you lost me on this line:

Horse.eat(Horse h) is not even considered, since c.eat(h) can only call methods known to class Cattle.

According to Harsh Singh:
now for the line c.eat(h);
At the compile time it binds it to eat(Mammal) of the Cattle class.
At the runtime it runs the eat(Mammal) of the object Horse.

So we are concerned with the runtime value of c (Horse) and the compile time value of its argument h (Mammal).

Run the following code:


class Mammal {
void eat(Mammal m) {
System.out.println("Mammal eats food");
}
}

class Cattle extends Mammal {
void eat(Cattle c) {
System.out.println("Cattle eats food");
}
}

class Horse extends Cattle {
void eat(Horse h) {
System.out.println("Horse eats food");
}
void eat(Mammal h) {
System.out.println("Horse Mammal eats food");
}
}

public class Test {
public static void main(String[] args) {
Mammal h = null;
Cattle c = new Horse();
c.eat(h);
}
}

prints "Horse Mammal eats food"
I missed this problem on one of the practice tests and I just want to be sure that I understand the reasoning behind the answer correctly.


prints "Mammal eats food"

I just want to be sure that I understand the reasoning behind this correctly.

The object c is governed by the runtime setting Horse, but the parameter h, which is passed to the method is governed by the compile-time setting Mammal. So it doesn�t matter whether h is set to a run-time setting of Horse, Cattle or Mammal, its compile-time value of Mammal is used to find the matching method type.

Since the class Horse doesn't contain a "void eat(Mammal h)" method, and the class Cattle also doesn't contain a "void eat(Mammal h)" method, it finally passes to the Mammal class, which does contain the matching method and type.

If the object c was set to Cattle, then it would start looking at the Cattle level for the matching method and then start moving up towards it parent classes.

Is this correct?

( tags added)
[ January 11, 2005: Message edited by: Barry Gaunt ]
Sorry about the first example, that was a simple typo (met1 and met2) that somehow slipped in.

Also thanks for the explanation, I found the original problem on a sample exam and then verified it on my local machine (which happened to have a JDK 1.3.1 compiler, where it give me the error. I subsequently ran it on the JDK 1.4.2 compiler and got the answer 20.
On the the following code sample:

class Test6 {
void met1(long x, long y) { System.out.println("long"); }
void met2(int x, int y) { System.out.println("int"); }

public static void main(String[] args) {
Test6 t = new Test6();
t.met1(10, 6);
}
}

The more specific match (long) is choosen and the answer "long" is printed.

But on the following:

class Rectangle {
public int area(int length, int width) {
return length * width;
}
}

class Square extends Rectangle {
public int area(long length, long width) {
return (int) Math.pow(length, 2);
}
}

class Test4 {
public static void main(String[] args) {
Square r = new Square();
System.out.println(r.area(5, 4));
}
}

generates the following error:
reference to area is ambiguous, both method area(int,int) in Rect
angle and method area(long,long) in Square match

I don't understand why the more specific match rule doesn't apply in this case. The area method should be overloaded and the Square class should contain both of the area methods, so that it reduces to the same situation as in the first example.

Clearly, I don't understand something correctly