格式化代码
This commit is contained in:
@@ -111,7 +111,7 @@
|
|||||||
<!--Should BigEgg$Yolk be a _static_ inner class?-->
|
<!--Should BigEgg$Yolk be a _static_ inner class?-->
|
||||||
<!--Should Egg$Yolk be a _static_ inner class?-->
|
<!--Should Egg$Yolk be a _static_ inner class?-->
|
||||||
</Match>
|
</Match>
|
||||||
<!-------- Checked to here ------------------------------------------------->
|
<!-------- Checked to here ------------------------------------------------->
|
||||||
<Match class="Equivalence">
|
<Match class="Equivalence">
|
||||||
<BugCode name="RC"/>
|
<BugCode name="RC"/>
|
||||||
<!--Suspicious comparison of java.lang.Integer references in Equivalence.main(String[]) At Equivalence.java:[line 7]-->
|
<!--Suspicious comparison of java.lang.Integer references in Equivalence.main(String[]) At Equivalence.java:[line 7]-->
|
||||||
|
|||||||
@@ -1,14 +1,17 @@
|
|||||||
package access;//: access/ChocolateChip.java
|
package access;//: access/ChocolateChip.java
|
||||||
// Can't use package-access member from another package.
|
// Can't use package-access member from another package.
|
||||||
|
|
||||||
import access.dessert.*;
|
import access.dessert.*;
|
||||||
|
|
||||||
public class ChocolateChip extends Cookie {
|
public class ChocolateChip extends Cookie {
|
||||||
public ChocolateChip() {
|
public ChocolateChip() {
|
||||||
System.out.println("ChocolateChip constructor");
|
System.out.println("ChocolateChip constructor");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void chomp() {
|
public void chomp() {
|
||||||
//! bite(); // Can't access bite
|
//! bite(); // Can't access bite
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
ChocolateChip x = new ChocolateChip();
|
ChocolateChip x = new ChocolateChip();
|
||||||
x.chomp();
|
x.chomp();
|
||||||
|
|||||||
@@ -1,11 +1,16 @@
|
|||||||
package access;//: access/ChocolateChip2.java
|
package access;//: access/ChocolateChip2.java
|
||||||
|
|
||||||
import access.cookie2.*;
|
import access.cookie2.*;
|
||||||
|
|
||||||
public class ChocolateChip2 extends Cookie {
|
public class ChocolateChip2 extends Cookie {
|
||||||
public ChocolateChip2() {
|
public ChocolateChip2() {
|
||||||
System.out.println("ChocolateChip2 constructor");
|
System.out.println("ChocolateChip2 constructor");
|
||||||
}
|
}
|
||||||
public void chomp() { bite(); } // Protected method
|
|
||||||
|
public void chomp() {
|
||||||
|
bite();
|
||||||
|
} // Protected method
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
ChocolateChip2 x = new ChocolateChip2();
|
ChocolateChip2 x = new ChocolateChip2();
|
||||||
x.chomp();
|
x.chomp();
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package access;//: access/Dinner.java
|
package access;//: access/Dinner.java
|
||||||
// Uses the library.
|
// Uses the library.
|
||||||
|
|
||||||
import access.dessert.*;
|
import access.dessert.*;
|
||||||
|
|
||||||
public class Dinner {
|
public class Dinner {
|
||||||
|
|||||||
@@ -2,7 +2,9 @@ package access;//: access/IceCream.java
|
|||||||
// Demonstrates "private" keyword.
|
// Demonstrates "private" keyword.
|
||||||
|
|
||||||
class Sundae {
|
class Sundae {
|
||||||
private Sundae() {}
|
private Sundae() {
|
||||||
|
}
|
||||||
|
|
||||||
static Sundae makeASundae() {
|
static Sundae makeASundae() {
|
||||||
return new Sundae();
|
return new Sundae();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
package access;//: access/ImportedMyClass.java
|
package access;//: access/ImportedMyClass.java
|
||||||
|
|
||||||
import access.mypackage.*;
|
import access.mypackage.*;
|
||||||
|
|
||||||
public class ImportedMyClass {
|
public class ImportedMyClass {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package access;//: access/LibTest.java
|
package access;//: access/LibTest.java
|
||||||
// Uses the library.
|
// Uses the library.
|
||||||
|
|
||||||
import net.mindview.simple.*;
|
import net.mindview.simple.*;
|
||||||
|
|
||||||
public class LibTest {
|
public class LibTest {
|
||||||
|
|||||||
@@ -3,7 +3,9 @@ package access;//: access/Lunch.java
|
|||||||
// effectively private with private constructors:
|
// effectively private with private constructors:
|
||||||
|
|
||||||
class Soup1 {
|
class Soup1 {
|
||||||
private Soup1() {}
|
private Soup1() {
|
||||||
|
}
|
||||||
|
|
||||||
// (1) Allow creation via static method:
|
// (1) Allow creation via static method:
|
||||||
public static Soup1 makeSoup() {
|
public static Soup1 makeSoup() {
|
||||||
return new Soup1();
|
return new Soup1();
|
||||||
@@ -11,14 +13,19 @@ class Soup1 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class Soup2 {
|
class Soup2 {
|
||||||
private Soup2() {}
|
private Soup2() {
|
||||||
|
}
|
||||||
|
|
||||||
// (2) Create a static object and return a reference
|
// (2) Create a static object and return a reference
|
||||||
// upon request.(The "Singleton" pattern):
|
// upon request.(The "Singleton" pattern):
|
||||||
private static Soup2 ps1 = new Soup2();
|
private static Soup2 ps1 = new Soup2();
|
||||||
|
|
||||||
public static Soup2 access() {
|
public static Soup2 access() {
|
||||||
return ps1;
|
return ps1;
|
||||||
}
|
}
|
||||||
public void f() {}
|
|
||||||
|
public void f() {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only one public class allowed per file:
|
// Only one public class allowed per file:
|
||||||
@@ -27,9 +34,11 @@ public class Lunch {
|
|||||||
// Can't do this! Private constructor:
|
// Can't do this! Private constructor:
|
||||||
//! Soup1 soup = new Soup1();
|
//! Soup1 soup = new Soup1();
|
||||||
}
|
}
|
||||||
|
|
||||||
void testStatic() {
|
void testStatic() {
|
||||||
Soup1 soup = Soup1.makeSoup();
|
Soup1 soup = Soup1.makeSoup();
|
||||||
}
|
}
|
||||||
|
|
||||||
void testSingleton() {
|
void testSingleton() {
|
||||||
Soup2.access().f();
|
Soup2.access().f();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,11 +2,17 @@ package access;//: access/OrganizedByAccess.java
|
|||||||
|
|
||||||
public class OrganizedByAccess {
|
public class OrganizedByAccess {
|
||||||
public void pub1() { /* ... */ }
|
public void pub1() { /* ... */ }
|
||||||
|
|
||||||
public void pub2() { /* ... */ }
|
public void pub2() { /* ... */ }
|
||||||
|
|
||||||
public void pub3() { /* ... */ }
|
public void pub3() { /* ... */ }
|
||||||
|
|
||||||
private void priv1() { /* ... */ }
|
private void priv1() { /* ... */ }
|
||||||
|
|
||||||
private void priv2() { /* ... */ }
|
private void priv2() { /* ... */ }
|
||||||
|
|
||||||
private void priv3() { /* ... */ }
|
private void priv3() { /* ... */ }
|
||||||
|
|
||||||
private int i;
|
private int i;
|
||||||
// ...
|
// ...
|
||||||
} ///:~
|
} ///:~
|
||||||
|
|||||||
@@ -2,5 +2,7 @@ package access;//: access/Pie.java
|
|||||||
// The other class.
|
// The other class.
|
||||||
|
|
||||||
class Pie {
|
class Pie {
|
||||||
void f() { System.out.println("Pie.f()"); }
|
void f() {
|
||||||
|
System.out.println("Pie.f()");
|
||||||
|
}
|
||||||
} ///:~
|
} ///:~
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package access;//: access/PrintTest.java
|
package access;//: access/PrintTest.java
|
||||||
// Uses the static printing methods in Print.java.
|
// Uses the static printing methods in Print.java.
|
||||||
|
|
||||||
import static net.mindview.util.Print.*;
|
import static net.mindview.util.Print.*;
|
||||||
|
|
||||||
public class PrintTest {
|
public class PrintTest {
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
package access;//: access/SingleImport.java
|
package access;//: access/SingleImport.java
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
public class SingleImport {
|
public class SingleImport {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ public class Cookie {
|
|||||||
public Cookie() {
|
public Cookie() {
|
||||||
System.out.println("Cookie constructor");
|
System.out.println("Cookie constructor");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void bite() {
|
protected void bite() {
|
||||||
System.out.println("bite");
|
System.out.println("bite");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,5 +6,8 @@ public class Cookie {
|
|||||||
public Cookie() {
|
public Cookie() {
|
||||||
System.out.println("Cookie constructor");
|
System.out.println("Cookie constructor");
|
||||||
}
|
}
|
||||||
void bite() { System.out.println("bite"); }
|
|
||||||
|
void bite() {
|
||||||
|
System.out.println("bite");
|
||||||
|
}
|
||||||
} ///:~
|
} ///:~
|
||||||
|
|||||||
@@ -1,18 +1,24 @@
|
|||||||
//: annotations/AtUnitComposition.java
|
//: annotations/AtUnitComposition.java
|
||||||
// Creating non-embedded tests.
|
// Creating non-embedded tests.
|
||||||
package annotations;
|
package annotations;
|
||||||
|
|
||||||
import net.mindview.atunit.*;
|
import net.mindview.atunit.*;
|
||||||
import net.mindview.util.*;
|
import net.mindview.util.*;
|
||||||
|
|
||||||
public class AtUnitComposition {
|
public class AtUnitComposition {
|
||||||
AtUnitExample1 testObject = new AtUnitExample1();
|
AtUnitExample1 testObject = new AtUnitExample1();
|
||||||
@Test boolean _methodOne() {
|
|
||||||
|
@Test
|
||||||
|
boolean _methodOne() {
|
||||||
return
|
return
|
||||||
testObject.methodOne().equals("This is methodOne");
|
testObject.methodOne().equals("This is methodOne");
|
||||||
}
|
}
|
||||||
@Test boolean _methodTwo() {
|
|
||||||
|
@Test
|
||||||
|
boolean _methodTwo() {
|
||||||
return testObject.methodTwo() == 2;
|
return testObject.methodTwo() == 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
OSExecute.command(
|
OSExecute.command(
|
||||||
"java net.mindview.atunit.AtUnit AtUnitComposition");
|
"java net.mindview.atunit.AtUnit AtUnitComposition");
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
//: annotations/AtUnitExample1.java
|
//: annotations/AtUnitExample1.java
|
||||||
package annotations;
|
package annotations;
|
||||||
|
|
||||||
import net.mindview.atunit.*;
|
import net.mindview.atunit.*;
|
||||||
import net.mindview.util.*;
|
import net.mindview.util.*;
|
||||||
|
|
||||||
@@ -7,18 +8,38 @@ public class AtUnitExample1 {
|
|||||||
public String methodOne() {
|
public String methodOne() {
|
||||||
return "This is methodOne";
|
return "This is methodOne";
|
||||||
}
|
}
|
||||||
|
|
||||||
public int methodTwo() {
|
public int methodTwo() {
|
||||||
System.out.println("This is methodTwo");
|
System.out.println("This is methodTwo");
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
@Test boolean methodOneTest() {
|
|
||||||
|
@Test
|
||||||
|
boolean methodOneTest() {
|
||||||
return methodOne().equals("This is methodOne");
|
return methodOne().equals("This is methodOne");
|
||||||
}
|
}
|
||||||
@Test boolean m2() { return methodTwo() == 2; }
|
|
||||||
@Test private boolean m3() { return true; }
|
@Test
|
||||||
|
boolean m2() {
|
||||||
|
return methodTwo() == 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
private boolean m3() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Shows output for failure:
|
// Shows output for failure:
|
||||||
@Test boolean failureTest() { return false; }
|
@Test
|
||||||
@Test boolean anotherDisappointment() { return false; }
|
boolean failureTest() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
boolean anotherDisappointment() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
OSExecute.command(
|
OSExecute.command(
|
||||||
"java net.mindview.atunit.AtUnit AtUnitExample1");
|
"java net.mindview.atunit.AtUnit AtUnitExample1");
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
//: annotations/AtUnitExample2.java
|
//: annotations/AtUnitExample2.java
|
||||||
// Assertions and exceptions can be used in @Tests.
|
// Assertions and exceptions can be used in @Tests.
|
||||||
package annotations;
|
package annotations;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
|
||||||
import net.mindview.atunit.*;
|
import net.mindview.atunit.*;
|
||||||
import net.mindview.util.*;
|
import net.mindview.util.*;
|
||||||
|
|
||||||
@@ -9,24 +11,34 @@ public class AtUnitExample2 {
|
|||||||
public String methodOne() {
|
public String methodOne() {
|
||||||
return "This is methodOne";
|
return "This is methodOne";
|
||||||
}
|
}
|
||||||
|
|
||||||
public int methodTwo() {
|
public int methodTwo() {
|
||||||
System.out.println("This is methodTwo");
|
System.out.println("This is methodTwo");
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
@Test void assertExample() {
|
|
||||||
|
@Test
|
||||||
|
void assertExample() {
|
||||||
assert methodOne().equals("This is methodOne");
|
assert methodOne().equals("This is methodOne");
|
||||||
}
|
}
|
||||||
@Test void assertFailureExample() {
|
|
||||||
assert 1 == 2: "What a surprise!";
|
@Test
|
||||||
|
void assertFailureExample() {
|
||||||
|
assert 1 == 2 : "What a surprise!";
|
||||||
}
|
}
|
||||||
@Test void exceptionExample() throws IOException {
|
|
||||||
|
@Test
|
||||||
|
void exceptionExample() throws IOException {
|
||||||
new FileInputStream("nofile.txt"); // Throws
|
new FileInputStream("nofile.txt"); // Throws
|
||||||
}
|
}
|
||||||
@Test boolean assertAndReturn() {
|
|
||||||
|
@Test
|
||||||
|
boolean assertAndReturn() {
|
||||||
// Assertion with message:
|
// Assertion with message:
|
||||||
assert methodTwo() == 2: "methodTwo must equal 2";
|
assert methodTwo() == 2 : "methodTwo must equal 2";
|
||||||
return methodOne().equals("This is methodOne");
|
return methodOne().equals("This is methodOne");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
OSExecute.command(
|
OSExecute.command(
|
||||||
"java net.mindview.atunit.AtUnit AtUnitExample2");
|
"java net.mindview.atunit.AtUnit AtUnitExample2");
|
||||||
|
|||||||
@@ -1,27 +1,49 @@
|
|||||||
//: annotations/AtUnitExample3.java
|
//: annotations/AtUnitExample3.java
|
||||||
package annotations;
|
package annotations;
|
||||||
|
|
||||||
import net.mindview.atunit.*;
|
import net.mindview.atunit.*;
|
||||||
import net.mindview.util.*;
|
import net.mindview.util.*;
|
||||||
|
|
||||||
public class AtUnitExample3 {
|
public class AtUnitExample3 {
|
||||||
private int n;
|
private int n;
|
||||||
public AtUnitExample3(int n) { this.n = n; }
|
|
||||||
public int getN() { return n; }
|
public AtUnitExample3(int n) {
|
||||||
|
this.n = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getN() {
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
public String methodOne() {
|
public String methodOne() {
|
||||||
return "This is methodOne";
|
return "This is methodOne";
|
||||||
}
|
}
|
||||||
|
|
||||||
public int methodTwo() {
|
public int methodTwo() {
|
||||||
System.out.println("This is methodTwo");
|
System.out.println("This is methodTwo");
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
@TestObjectCreate static AtUnitExample3 create() {
|
|
||||||
|
@TestObjectCreate
|
||||||
|
static AtUnitExample3 create() {
|
||||||
return new AtUnitExample3(47);
|
return new AtUnitExample3(47);
|
||||||
}
|
}
|
||||||
@Test boolean initialization() { return n == 47; }
|
|
||||||
@Test boolean methodOneTest() {
|
@Test
|
||||||
|
boolean initialization() {
|
||||||
|
return n == 47;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
boolean methodOneTest() {
|
||||||
return methodOne().equals("This is methodOne");
|
return methodOne().equals("This is methodOne");
|
||||||
}
|
}
|
||||||
@Test boolean m2() { return methodTwo() == 2; }
|
|
||||||
|
@Test
|
||||||
|
boolean m2() {
|
||||||
|
return methodTwo() == 2;
|
||||||
|
}
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
OSExecute.command(
|
OSExecute.command(
|
||||||
"java net.mindview.atunit.AtUnit AtUnitExample3");
|
"java net.mindview.atunit.AtUnit AtUnitExample3");
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
//: annotations/AtUnitExample4.java
|
//: annotations/AtUnitExample4.java
|
||||||
package annotations;
|
package annotations;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import net.mindview.atunit.*;
|
import net.mindview.atunit.*;
|
||||||
import net.mindview.util.*;
|
import net.mindview.util.*;
|
||||||
|
|
||||||
import static net.mindview.util.Print.*;
|
import static net.mindview.util.Print.*;
|
||||||
|
|
||||||
public class AtUnitExample4 {
|
public class AtUnitExample4 {
|
||||||
@@ -11,36 +14,51 @@ public class AtUnitExample4 {
|
|||||||
"middle, and then thin again at the far end.";
|
"middle, and then thin again at the far end.";
|
||||||
private String word;
|
private String word;
|
||||||
private Random rand = new Random(); // Time-based seed
|
private Random rand = new Random(); // Time-based seed
|
||||||
public AtUnitExample4(String word) { this.word = word; }
|
|
||||||
public String getWord() { return word; }
|
public AtUnitExample4(String word) {
|
||||||
|
this.word = word;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getWord() {
|
||||||
|
return word;
|
||||||
|
}
|
||||||
|
|
||||||
public String scrambleWord() {
|
public String scrambleWord() {
|
||||||
List<Character> chars = new ArrayList<Character>();
|
List<Character> chars = new ArrayList<Character>();
|
||||||
for(Character c : word.toCharArray()) {
|
for (Character c : word.toCharArray()) {
|
||||||
chars.add(c);
|
chars.add(c);
|
||||||
}
|
}
|
||||||
Collections.shuffle(chars, rand);
|
Collections.shuffle(chars, rand);
|
||||||
StringBuilder result = new StringBuilder();
|
StringBuilder result = new StringBuilder();
|
||||||
for(char ch : chars) {
|
for (char ch : chars) {
|
||||||
result.append(ch);
|
result.append(ch);
|
||||||
}
|
}
|
||||||
return result.toString();
|
return result.toString();
|
||||||
}
|
}
|
||||||
@TestProperty static List<String> input =
|
|
||||||
|
@TestProperty
|
||||||
|
static List<String> input =
|
||||||
Arrays.asList(theory.split(" "));
|
Arrays.asList(theory.split(" "));
|
||||||
@TestProperty
|
@TestProperty
|
||||||
static Iterator<String> words = input.iterator();
|
static Iterator<String> words = input.iterator();
|
||||||
@TestObjectCreate static AtUnitExample4 create() {
|
|
||||||
if(words.hasNext()) {
|
@TestObjectCreate
|
||||||
|
static AtUnitExample4 create() {
|
||||||
|
if (words.hasNext()) {
|
||||||
return new AtUnitExample4(words.next());
|
return new AtUnitExample4(words.next());
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@Test boolean words() {
|
|
||||||
|
@Test
|
||||||
|
boolean words() {
|
||||||
print("'" + getWord() + "'");
|
print("'" + getWord() + "'");
|
||||||
return getWord().equals("are");
|
return getWord().equals("are");
|
||||||
}
|
}
|
||||||
@Test boolean scramble1() {
|
|
||||||
|
@Test
|
||||||
|
boolean scramble1() {
|
||||||
// Change to a specific seed to get verifiable results:
|
// Change to a specific seed to get verifiable results:
|
||||||
rand = new Random(47);
|
rand = new Random(47);
|
||||||
print("'" + getWord() + "'");
|
print("'" + getWord() + "'");
|
||||||
@@ -48,13 +66,16 @@ public class AtUnitExample4 {
|
|||||||
print(scrambled);
|
print(scrambled);
|
||||||
return scrambled.equals("lAl");
|
return scrambled.equals("lAl");
|
||||||
}
|
}
|
||||||
@Test boolean scramble2() {
|
|
||||||
|
@Test
|
||||||
|
boolean scramble2() {
|
||||||
rand = new Random(74);
|
rand = new Random(74);
|
||||||
print("'" + getWord() + "'");
|
print("'" + getWord() + "'");
|
||||||
String scrambled = scrambleWord();
|
String scrambled = scrambleWord();
|
||||||
print(scrambled);
|
print(scrambled);
|
||||||
return scrambled.equals("tsaeborornussu");
|
return scrambled.equals("tsaeborornussu");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
System.out.println("starting");
|
System.out.println("starting");
|
||||||
OSExecute.command(
|
OSExecute.command(
|
||||||
|
|||||||
@@ -1,41 +1,64 @@
|
|||||||
//: annotations/AtUnitExample5.java
|
//: annotations/AtUnitExample5.java
|
||||||
package annotations;
|
package annotations;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
|
||||||
import net.mindview.atunit.*;
|
import net.mindview.atunit.*;
|
||||||
import net.mindview.util.*;
|
import net.mindview.util.*;
|
||||||
|
|
||||||
public class AtUnitExample5 {
|
public class AtUnitExample5 {
|
||||||
private String text;
|
private String text;
|
||||||
public AtUnitExample5(String text) { this.text = text; }
|
|
||||||
public String toString() { return text; }
|
public AtUnitExample5(String text) {
|
||||||
@TestProperty static PrintWriter output;
|
this.text = text;
|
||||||
@TestProperty static int counter;
|
}
|
||||||
@TestObjectCreate static AtUnitExample5 create() {
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestProperty
|
||||||
|
static PrintWriter output;
|
||||||
|
@TestProperty
|
||||||
|
static int counter;
|
||||||
|
|
||||||
|
@TestObjectCreate
|
||||||
|
static AtUnitExample5 create() {
|
||||||
String id = Integer.toString(counter++);
|
String id = Integer.toString(counter++);
|
||||||
try {
|
try {
|
||||||
output = new PrintWriter("Test" + id + ".txt");
|
output = new PrintWriter("Test" + id + ".txt");
|
||||||
} catch(IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
return new AtUnitExample5(id);
|
return new AtUnitExample5(id);
|
||||||
}
|
}
|
||||||
@TestObjectCleanup static void
|
|
||||||
|
@TestObjectCleanup
|
||||||
|
static void
|
||||||
cleanup(AtUnitExample5 tobj) {
|
cleanup(AtUnitExample5 tobj) {
|
||||||
System.out.println("Running cleanup");
|
System.out.println("Running cleanup");
|
||||||
output.close();
|
output.close();
|
||||||
}
|
}
|
||||||
@Test boolean test1() {
|
|
||||||
|
@Test
|
||||||
|
boolean test1() {
|
||||||
output.print("test1");
|
output.print("test1");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@Test boolean test2() {
|
|
||||||
|
@Test
|
||||||
|
boolean test2() {
|
||||||
output.print("test2");
|
output.print("test2");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@Test boolean test3() {
|
|
||||||
|
@Test
|
||||||
|
boolean test3() {
|
||||||
output.print("test3");
|
output.print("test3");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
OSExecute.command(
|
OSExecute.command(
|
||||||
"java net.mindview.atunit.AtUnit AtUnitExample5");
|
"java net.mindview.atunit.AtUnit AtUnitExample5");
|
||||||
|
|||||||
@@ -1,14 +1,21 @@
|
|||||||
//: annotations/AtUnitExternalTest.java
|
//: annotations/AtUnitExternalTest.java
|
||||||
// Creating non-embedded tests.
|
// Creating non-embedded tests.
|
||||||
package annotations;
|
package annotations;
|
||||||
|
|
||||||
import net.mindview.atunit.*;
|
import net.mindview.atunit.*;
|
||||||
import net.mindview.util.*;
|
import net.mindview.util.*;
|
||||||
|
|
||||||
public class AtUnitExternalTest extends AtUnitExample1 {
|
public class AtUnitExternalTest extends AtUnitExample1 {
|
||||||
@Test boolean _methodOne() {
|
@Test
|
||||||
|
boolean _methodOne() {
|
||||||
return methodOne().equals("This is methodOne");
|
return methodOne().equals("This is methodOne");
|
||||||
}
|
}
|
||||||
@Test boolean _methodTwo() { return methodTwo() == 2; }
|
|
||||||
|
@Test
|
||||||
|
boolean _methodTwo() {
|
||||||
|
return methodTwo() == 2;
|
||||||
|
}
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
OSExecute.command(
|
OSExecute.command(
|
||||||
"java net.mindview.atunit.AtUnit AtUnitExternalTest");
|
"java net.mindview.atunit.AtUnit AtUnitExternalTest");
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
//: annotations/ExtractInterface.java
|
//: annotations/ExtractInterface.java
|
||||||
// APT-based annotation processing.
|
// APT-based annotation processing.
|
||||||
package annotations;
|
package annotations;
|
||||||
|
|
||||||
import java.lang.annotation.*;
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
@Target(ElementType.TYPE)
|
@Target(ElementType.TYPE)
|
||||||
|
|||||||
@@ -1,23 +1,32 @@
|
|||||||
//: annotations/HashSetTest.java
|
//: annotations/HashSetTest.java
|
||||||
package annotations;
|
package annotations;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import net.mindview.atunit.*;
|
import net.mindview.atunit.*;
|
||||||
import net.mindview.util.*;
|
import net.mindview.util.*;
|
||||||
|
|
||||||
public class HashSetTest {
|
public class HashSetTest {
|
||||||
HashSet<String> testObject = new HashSet<String>();
|
HashSet<String> testObject = new HashSet<String>();
|
||||||
@Test void initialization() {
|
|
||||||
|
@Test
|
||||||
|
void initialization() {
|
||||||
assert testObject.isEmpty();
|
assert testObject.isEmpty();
|
||||||
}
|
}
|
||||||
@Test void _contains() {
|
|
||||||
|
@Test
|
||||||
|
void _contains() {
|
||||||
testObject.add("one");
|
testObject.add("one");
|
||||||
assert testObject.contains("one");
|
assert testObject.contains("one");
|
||||||
}
|
}
|
||||||
@Test void _remove() {
|
|
||||||
|
@Test
|
||||||
|
void _remove() {
|
||||||
testObject.add("one");
|
testObject.add("one");
|
||||||
testObject.remove("one");
|
testObject.remove("one");
|
||||||
assert testObject.isEmpty();
|
assert testObject.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
OSExecute.command(
|
OSExecute.command(
|
||||||
"java net.mindview.atunit.AtUnit HashSetTest");
|
"java net.mindview.atunit.AtUnit HashSetTest");
|
||||||
|
|||||||
@@ -4,8 +4,10 @@
|
|||||||
// annotations.InterfaceExtractorProcessorFactory
|
// annotations.InterfaceExtractorProcessorFactory
|
||||||
// Multiplier.java -s ../annotations}
|
// Multiplier.java -s ../annotations}
|
||||||
package annotations;
|
package annotations;
|
||||||
|
|
||||||
import com.sun.mirror.apt.*;
|
import com.sun.mirror.apt.*;
|
||||||
import com.sun.mirror.declaration.*;
|
import com.sun.mirror.declaration.*;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@@ -14,40 +16,44 @@ public class InterfaceExtractorProcessor
|
|||||||
private final AnnotationProcessorEnvironment env;
|
private final AnnotationProcessorEnvironment env;
|
||||||
private ArrayList<MethodDeclaration> interfaceMethods =
|
private ArrayList<MethodDeclaration> interfaceMethods =
|
||||||
new ArrayList<MethodDeclaration>();
|
new ArrayList<MethodDeclaration>();
|
||||||
|
|
||||||
public InterfaceExtractorProcessor(
|
public InterfaceExtractorProcessor(
|
||||||
AnnotationProcessorEnvironment env) { this.env = env; }
|
AnnotationProcessorEnvironment env) {
|
||||||
|
this.env = env;
|
||||||
|
}
|
||||||
|
|
||||||
public void process() {
|
public void process() {
|
||||||
for(TypeDeclaration typeDecl :
|
for (TypeDeclaration typeDecl :
|
||||||
env.getSpecifiedTypeDeclarations()) {
|
env.getSpecifiedTypeDeclarations()) {
|
||||||
ExtractInterface annot =
|
ExtractInterface annot =
|
||||||
typeDecl.getAnnotation(ExtractInterface.class);
|
typeDecl.getAnnotation(ExtractInterface.class);
|
||||||
if(annot == null) {
|
if (annot == null) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
for(MethodDeclaration m : typeDecl.getMethods()) {
|
for (MethodDeclaration m : typeDecl.getMethods()) {
|
||||||
if(m.getModifiers().contains(Modifier.PUBLIC) &&
|
if (m.getModifiers().contains(Modifier.PUBLIC) &&
|
||||||
!(m.getModifiers().contains(Modifier.STATIC))) {
|
!(m.getModifiers().contains(Modifier.STATIC))) {
|
||||||
interfaceMethods.add(m);
|
interfaceMethods.add(m);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(interfaceMethods.size() > 0) {
|
if (interfaceMethods.size() > 0) {
|
||||||
try {
|
try {
|
||||||
PrintWriter writer =
|
PrintWriter writer =
|
||||||
env.getFiler().createSourceFile(annot.value());
|
env.getFiler().createSourceFile(annot.value());
|
||||||
writer.println("package " +
|
writer.println("package " +
|
||||||
typeDecl.getPackage().getQualifiedName() +";");
|
typeDecl.getPackage().getQualifiedName() + ";");
|
||||||
writer.println("public interface " +
|
writer.println("public interface " +
|
||||||
annot.value() + " {");
|
annot.value() + " {");
|
||||||
for(MethodDeclaration m : interfaceMethods) {
|
for (MethodDeclaration m : interfaceMethods) {
|
||||||
writer.print(" public ");
|
writer.print(" public ");
|
||||||
writer.print(m.getReturnType() + " ");
|
writer.print(m.getReturnType() + " ");
|
||||||
writer.print(m.getSimpleName() + " (");
|
writer.print(m.getSimpleName() + " (");
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for(ParameterDeclaration parm :
|
for (ParameterDeclaration parm :
|
||||||
m.getParameters()) {
|
m.getParameters()) {
|
||||||
writer.print(parm.getType() + " " +
|
writer.print(parm.getType() + " " +
|
||||||
parm.getSimpleName());
|
parm.getSimpleName());
|
||||||
if(++i < m.getParameters().size()) {
|
if (++i < m.getParameters().size()) {
|
||||||
writer.print(", ");
|
writer.print(", ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -55,7 +61,7 @@ public class InterfaceExtractorProcessor
|
|||||||
}
|
}
|
||||||
writer.println("}");
|
writer.println("}");
|
||||||
writer.close();
|
writer.close();
|
||||||
} catch(IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
throw new RuntimeException(ioe);
|
throw new RuntimeException(ioe);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
//: annotations/InterfaceExtractorProcessorFactory.java
|
//: annotations/InterfaceExtractorProcessorFactory.java
|
||||||
// APT-based annotation processing.
|
// APT-based annotation processing.
|
||||||
package annotations;
|
package annotations;
|
||||||
|
|
||||||
import com.sun.mirror.apt.*;
|
import com.sun.mirror.apt.*;
|
||||||
import com.sun.mirror.declaration.*;
|
import com.sun.mirror.declaration.*;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class InterfaceExtractorProcessorFactory
|
public class InterfaceExtractorProcessorFactory
|
||||||
@@ -12,10 +14,12 @@ public class InterfaceExtractorProcessorFactory
|
|||||||
AnnotationProcessorEnvironment env) {
|
AnnotationProcessorEnvironment env) {
|
||||||
return new InterfaceExtractorProcessor(env);
|
return new InterfaceExtractorProcessor(env);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<String> supportedAnnotationTypes() {
|
public Collection<String> supportedAnnotationTypes() {
|
||||||
return
|
return
|
||||||
Collections.singleton("annotations.ExtractInterface");
|
Collections.singleton("annotations.ExtractInterface");
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<String> supportedOptions() {
|
public Collection<String> supportedOptions() {
|
||||||
return Collections.emptySet();
|
return Collections.emptySet();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,12 +6,16 @@ package annotations;
|
|||||||
public class Multiplier {
|
public class Multiplier {
|
||||||
public int multiply(int x, int y) {
|
public int multiply(int x, int y) {
|
||||||
int total = 0;
|
int total = 0;
|
||||||
for(int i = 0; i < x; i++) {
|
for (int i = 0; i < x; i++) {
|
||||||
total = add(total, y);
|
total = add(total, y);
|
||||||
}
|
}
|
||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
private int add(int x, int y) { return x + y; }
|
|
||||||
|
private int add(int x, int y) {
|
||||||
|
return x + y;
|
||||||
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
Multiplier m = new Multiplier();
|
Multiplier m = new Multiplier();
|
||||||
System.out.println("11*16 = " + m.multiply(11, 16));
|
System.out.println("11*16 = " + m.multiply(11, 16));
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
package annotations;//: annotations/PasswordUtils.java
|
package annotations;//: annotations/PasswordUtils.java
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class PasswordUtils {
|
public class PasswordUtils {
|
||||||
@@ -7,10 +8,12 @@ public class PasswordUtils {
|
|||||||
public boolean validatePassword(String password) {
|
public boolean validatePassword(String password) {
|
||||||
return (password.matches("\\w*\\d\\w*"));
|
return (password.matches("\\w*\\d\\w*"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@UseCase(id = 48)
|
@UseCase(id = 48)
|
||||||
public String encryptPassword(String password) {
|
public String encryptPassword(String password) {
|
||||||
return new StringBuilder(password).reverse().toString();
|
return new StringBuilder(password).reverse().toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@UseCase(id = 49, description =
|
@UseCase(id = 49, description =
|
||||||
"New passwords can't equal previously used ones")
|
"New passwords can't equal previously used ones")
|
||||||
public boolean checkForNewPassword(
|
public boolean checkForNewPassword(
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
package annotations;//: annotations/SimulatingNull.java
|
package annotations;//: annotations/SimulatingNull.java
|
||||||
|
|
||||||
import java.lang.annotation.*;
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
@Target(ElementType.METHOD)
|
@Target(ElementType.METHOD)
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
public @interface SimulatingNull {
|
public @interface SimulatingNull {
|
||||||
public int id() default -1;
|
public int id() default -1;
|
||||||
|
|
||||||
public String description() default "";
|
public String description() default "";
|
||||||
} ///:~
|
} ///:~
|
||||||
|
|||||||
@@ -1,11 +1,21 @@
|
|||||||
//: annotations/StackL.java
|
//: annotations/StackL.java
|
||||||
// A stack built on a linkedList.
|
// A stack built on a linkedList.
|
||||||
package annotations;
|
package annotations;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class StackL<T> {
|
public class StackL<T> {
|
||||||
private LinkedList<T> list = new LinkedList<T>();
|
private LinkedList<T> list = new LinkedList<T>();
|
||||||
public void push(T v) { list.addFirst(v); }
|
|
||||||
public T top() { return list.getFirst(); }
|
public void push(T v) {
|
||||||
public T pop() { return list.removeFirst(); }
|
list.addFirst(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
public T top() {
|
||||||
|
return list.getFirst();
|
||||||
|
}
|
||||||
|
|
||||||
|
public T pop() {
|
||||||
|
return list.removeFirst();
|
||||||
|
}
|
||||||
} ///:~
|
} ///:~
|
||||||
|
|||||||
@@ -1,28 +1,35 @@
|
|||||||
//: annotations/StackLStringTest.java
|
//: annotations/StackLStringTest.java
|
||||||
// Applying @Unit to generics.
|
// Applying @Unit to generics.
|
||||||
package annotations;
|
package annotations;
|
||||||
|
|
||||||
import net.mindview.atunit.*;
|
import net.mindview.atunit.*;
|
||||||
import net.mindview.util.*;
|
import net.mindview.util.*;
|
||||||
|
|
||||||
public class StackLStringTest extends StackL<String> {
|
public class StackLStringTest extends StackL<String> {
|
||||||
@Test void _push() {
|
@Test
|
||||||
|
void _push() {
|
||||||
push("one");
|
push("one");
|
||||||
assert top().equals("one");
|
assert top().equals("one");
|
||||||
push("two");
|
push("two");
|
||||||
assert top().equals("two");
|
assert top().equals("two");
|
||||||
}
|
}
|
||||||
@Test void _pop() {
|
|
||||||
|
@Test
|
||||||
|
void _pop() {
|
||||||
push("one");
|
push("one");
|
||||||
push("two");
|
push("two");
|
||||||
assert pop().equals("two");
|
assert pop().equals("two");
|
||||||
assert pop().equals("one");
|
assert pop().equals("one");
|
||||||
}
|
}
|
||||||
@Test void _top() {
|
|
||||||
|
@Test
|
||||||
|
void _top() {
|
||||||
push("A");
|
push("A");
|
||||||
push("B");
|
push("B");
|
||||||
assert top().equals("B");
|
assert top().equals("B");
|
||||||
assert top().equals("B");
|
assert top().equals("B");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
OSExecute.command(
|
OSExecute.command(
|
||||||
"java net.mindview.atunit.AtUnit StackLStringTest");
|
"java net.mindview.atunit.AtUnit StackLStringTest");
|
||||||
|
|||||||
@@ -1,10 +1,15 @@
|
|||||||
//: annotations/Testable.java
|
//: annotations/Testable.java
|
||||||
package annotations;
|
package annotations;
|
||||||
|
|
||||||
import net.mindview.atunit.*;
|
import net.mindview.atunit.*;
|
||||||
|
|
||||||
public class Testable {
|
public class Testable {
|
||||||
public void execute() {
|
public void execute() {
|
||||||
System.out.println("Executing..");
|
System.out.println("Executing..");
|
||||||
}
|
}
|
||||||
@Test void testExecute() { execute(); }
|
|
||||||
|
@Test
|
||||||
|
void testExecute() {
|
||||||
|
execute();
|
||||||
|
}
|
||||||
} ///:~
|
} ///:~
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
package annotations;//: annotations/UseCase.java
|
package annotations;//: annotations/UseCase.java
|
||||||
|
|
||||||
import java.lang.annotation.*;
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
@Target(ElementType.METHOD)
|
@Target(ElementType.METHOD)
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
public @interface UseCase {
|
public @interface UseCase {
|
||||||
public int id();
|
public int id();
|
||||||
|
|
||||||
public String description() default "no description";
|
public String description() default "no description";
|
||||||
} ///:~
|
} ///:~
|
||||||
|
|||||||
@@ -1,22 +1,24 @@
|
|||||||
package annotations;//: annotations/UseCaseTracker.java
|
package annotations;//: annotations/UseCaseTracker.java
|
||||||
|
|
||||||
import java.lang.reflect.*;
|
import java.lang.reflect.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class UseCaseTracker {
|
public class UseCaseTracker {
|
||||||
public static void
|
public static void
|
||||||
trackUseCases(List<Integer> useCases, Class<?> cl) {
|
trackUseCases(List<Integer> useCases, Class<?> cl) {
|
||||||
for(Method m : cl.getDeclaredMethods()) {
|
for (Method m : cl.getDeclaredMethods()) {
|
||||||
UseCase uc = m.getAnnotation(UseCase.class);
|
UseCase uc = m.getAnnotation(UseCase.class);
|
||||||
if(uc != null) {
|
if (uc != null) {
|
||||||
System.out.println("Found Use Case:" + uc.id() +
|
System.out.println("Found Use Case:" + uc.id() +
|
||||||
" " + uc.description());
|
" " + uc.description());
|
||||||
useCases.remove(new Integer(uc.id()));
|
useCases.remove(new Integer(uc.id()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(int i : useCases) {
|
for (int i : useCases) {
|
||||||
System.out.println("Warning: Missing use case-" + i);
|
System.out.println("Warning: Missing use case-" + i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
List<Integer> useCases = new ArrayList<Integer>();
|
List<Integer> useCases = new ArrayList<Integer>();
|
||||||
Collections.addAll(useCases, 47, 48, 49, 50);
|
Collections.addAll(useCases, 47, 48, 49, 50);
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
//: annotations/database/Constraints.java
|
//: annotations/database/Constraints.java
|
||||||
package annotations.database;
|
package annotations.database;
|
||||||
|
|
||||||
import java.lang.annotation.*;
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
@Target(ElementType.FIELD)
|
@Target(ElementType.FIELD)
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
public @interface Constraints {
|
public @interface Constraints {
|
||||||
boolean primaryKey() default false;
|
boolean primaryKey() default false;
|
||||||
|
|
||||||
boolean allowNull() default true;
|
boolean allowNull() default true;
|
||||||
|
|
||||||
boolean unique() default false;
|
boolean unique() default false;
|
||||||
} ///:~
|
} ///:~
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
//: annotations/database/DBTable.java
|
//: annotations/database/DBTable.java
|
||||||
package annotations.database;
|
package annotations.database;
|
||||||
|
|
||||||
import java.lang.annotation.*;
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
@Target(ElementType.TYPE) // Applies to classes only
|
@Target(ElementType.TYPE) // Applies to classes only
|
||||||
|
|||||||
@@ -3,16 +3,35 @@ package annotations.database;
|
|||||||
|
|
||||||
@DBTable(name = "MEMBER")
|
@DBTable(name = "MEMBER")
|
||||||
public class Member {
|
public class Member {
|
||||||
@SQLString(30) String firstName;
|
@SQLString(30)
|
||||||
@SQLString(50) String lastName;
|
String firstName;
|
||||||
@SQLInteger Integer age;
|
@SQLString(50)
|
||||||
|
String lastName;
|
||||||
|
@SQLInteger
|
||||||
|
Integer age;
|
||||||
@SQLString(value = 30,
|
@SQLString(value = 30,
|
||||||
constraints = @Constraints(primaryKey = true))
|
constraints = @Constraints(primaryKey = true))
|
||||||
String handle;
|
String handle;
|
||||||
static int memberCount;
|
static int memberCount;
|
||||||
public String getHandle() { return handle; }
|
|
||||||
public String getFirstName() { return firstName; }
|
public String getHandle() {
|
||||||
public String getLastName() { return lastName; }
|
return handle;
|
||||||
public String toString() { return handle; }
|
}
|
||||||
public Integer getAge() { return age; }
|
|
||||||
|
public String getFirstName() {
|
||||||
|
return firstName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLastName() {
|
||||||
|
return lastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getAge() {
|
||||||
|
return age;
|
||||||
|
}
|
||||||
} ///:~
|
} ///:~
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
//: annotations/database/SQLInteger.java
|
//: annotations/database/SQLInteger.java
|
||||||
package annotations.database;
|
package annotations.database;
|
||||||
|
|
||||||
import java.lang.annotation.*;
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
@Target(ElementType.FIELD)
|
@Target(ElementType.FIELD)
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
public @interface SQLInteger {
|
public @interface SQLInteger {
|
||||||
String name() default "";
|
String name() default "";
|
||||||
|
|
||||||
Constraints constraints() default @Constraints;
|
Constraints constraints() default @Constraints;
|
||||||
} ///:~
|
} ///:~
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
//: annotations/database/SQLString.java
|
//: annotations/database/SQLString.java
|
||||||
package annotations.database;
|
package annotations.database;
|
||||||
|
|
||||||
import java.lang.annotation.*;
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
@Target(ElementType.FIELD)
|
@Target(ElementType.FIELD)
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
public @interface SQLString {
|
public @interface SQLString {
|
||||||
int value() default 0;
|
int value() default 0;
|
||||||
|
|
||||||
String name() default "";
|
String name() default "";
|
||||||
|
|
||||||
Constraints constraints() default @Constraints;
|
Constraints constraints() default @Constraints;
|
||||||
} ///:~
|
} ///:~
|
||||||
|
|||||||
@@ -4,10 +4,13 @@
|
|||||||
// annotations.database.TableCreationProcessorFactory
|
// annotations.database.TableCreationProcessorFactory
|
||||||
// database/Member.java -s database}
|
// database/Member.java -s database}
|
||||||
package annotations.database;
|
package annotations.database;
|
||||||
|
|
||||||
import com.sun.mirror.apt.*;
|
import com.sun.mirror.apt.*;
|
||||||
import com.sun.mirror.declaration.*;
|
import com.sun.mirror.declaration.*;
|
||||||
import com.sun.mirror.util.*;
|
import com.sun.mirror.util.*;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import static com.sun.mirror.util.DeclarationVisitors.*;
|
import static com.sun.mirror.util.DeclarationVisitors.*;
|
||||||
|
|
||||||
public class TableCreationProcessorFactory
|
public class TableCreationProcessorFactory
|
||||||
@@ -17,6 +20,7 @@ public class TableCreationProcessorFactory
|
|||||||
AnnotationProcessorEnvironment env) {
|
AnnotationProcessorEnvironment env) {
|
||||||
return new TableCreationProcessor(env);
|
return new TableCreationProcessor(env);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<String> supportedAnnotationTypes() {
|
public Collection<String> supportedAnnotationTypes() {
|
||||||
return Arrays.asList(
|
return Arrays.asList(
|
||||||
"annotations.database.DBTable",
|
"annotations.database.DBTable",
|
||||||
@@ -24,19 +28,23 @@ public class TableCreationProcessorFactory
|
|||||||
"annotations.database.SQLString",
|
"annotations.database.SQLString",
|
||||||
"annotations.database.SQLInteger");
|
"annotations.database.SQLInteger");
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<String> supportedOptions() {
|
public Collection<String> supportedOptions() {
|
||||||
return Collections.emptySet();
|
return Collections.emptySet();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class TableCreationProcessor
|
private static class TableCreationProcessor
|
||||||
implements AnnotationProcessor {
|
implements AnnotationProcessor {
|
||||||
private final AnnotationProcessorEnvironment env;
|
private final AnnotationProcessorEnvironment env;
|
||||||
private String sql = "";
|
private String sql = "";
|
||||||
|
|
||||||
public TableCreationProcessor(
|
public TableCreationProcessor(
|
||||||
AnnotationProcessorEnvironment env) {
|
AnnotationProcessorEnvironment env) {
|
||||||
this.env = env;
|
this.env = env;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void process() {
|
public void process() {
|
||||||
for(TypeDeclaration typeDecl :
|
for (TypeDeclaration typeDecl :
|
||||||
env.getSpecifiedTypeDeclarations()) {
|
env.getSpecifiedTypeDeclarations()) {
|
||||||
typeDecl.accept(getDeclarationScanner(
|
typeDecl.accept(getDeclarationScanner(
|
||||||
new TableCreationVisitor(), NO_OP));
|
new TableCreationVisitor(), NO_OP));
|
||||||
@@ -45,12 +53,13 @@ public class TableCreationProcessorFactory
|
|||||||
sql = "";
|
sql = "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class TableCreationVisitor
|
private class TableCreationVisitor
|
||||||
extends SimpleDeclarationVisitor {
|
extends SimpleDeclarationVisitor {
|
||||||
public void visitClassDeclaration(
|
public void visitClassDeclaration(
|
||||||
ClassDeclaration d) {
|
ClassDeclaration d) {
|
||||||
DBTable dbTable = d.getAnnotation(DBTable.class);
|
DBTable dbTable = d.getAnnotation(DBTable.class);
|
||||||
if(dbTable != null) {
|
if (dbTable != null) {
|
||||||
sql += "CREATE TABLE ";
|
sql += "CREATE TABLE ";
|
||||||
sql += (dbTable.name().length() < 1)
|
sql += (dbTable.name().length() < 1)
|
||||||
? d.getSimpleName().toUpperCase()
|
? d.getSimpleName().toUpperCase()
|
||||||
@@ -58,14 +67,15 @@ public class TableCreationProcessorFactory
|
|||||||
sql += " (";
|
sql += " (";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void visitFieldDeclaration(
|
public void visitFieldDeclaration(
|
||||||
FieldDeclaration d) {
|
FieldDeclaration d) {
|
||||||
String columnName = "";
|
String columnName = "";
|
||||||
if(d.getAnnotation(SQLInteger.class) != null) {
|
if (d.getAnnotation(SQLInteger.class) != null) {
|
||||||
SQLInteger sInt = d.getAnnotation(
|
SQLInteger sInt = d.getAnnotation(
|
||||||
SQLInteger.class);
|
SQLInteger.class);
|
||||||
// Use field name if name not specified
|
// Use field name if name not specified
|
||||||
if(sInt.name().length() < 1) {
|
if (sInt.name().length() < 1) {
|
||||||
columnName = d.getSimpleName().toUpperCase();
|
columnName = d.getSimpleName().toUpperCase();
|
||||||
} else {
|
} else {
|
||||||
columnName = sInt.name();
|
columnName = sInt.name();
|
||||||
@@ -73,11 +83,11 @@ public class TableCreationProcessorFactory
|
|||||||
sql += "\n " + columnName + " INT" +
|
sql += "\n " + columnName + " INT" +
|
||||||
getConstraints(sInt.constraints()) + ",";
|
getConstraints(sInt.constraints()) + ",";
|
||||||
}
|
}
|
||||||
if(d.getAnnotation(SQLString.class) != null) {
|
if (d.getAnnotation(SQLString.class) != null) {
|
||||||
SQLString sString = d.getAnnotation(
|
SQLString sString = d.getAnnotation(
|
||||||
SQLString.class);
|
SQLString.class);
|
||||||
// Use field name if name not specified.
|
// Use field name if name not specified.
|
||||||
if(sString.name().length() < 1) {
|
if (sString.name().length() < 1) {
|
||||||
columnName = d.getSimpleName().toUpperCase();
|
columnName = d.getSimpleName().toUpperCase();
|
||||||
} else {
|
} else {
|
||||||
columnName = sString.name();
|
columnName = sString.name();
|
||||||
@@ -87,15 +97,16 @@ public class TableCreationProcessorFactory
|
|||||||
getConstraints(sString.constraints()) + ",";
|
getConstraints(sString.constraints()) + ",";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getConstraints(Constraints con) {
|
private String getConstraints(Constraints con) {
|
||||||
String constraints = "";
|
String constraints = "";
|
||||||
if(!con.allowNull()) {
|
if (!con.allowNull()) {
|
||||||
constraints += " NOT NULL";
|
constraints += " NOT NULL";
|
||||||
}
|
}
|
||||||
if(con.primaryKey()) {
|
if (con.primaryKey()) {
|
||||||
constraints += " PRIMARY KEY";
|
constraints += " PRIMARY KEY";
|
||||||
}
|
}
|
||||||
if(con.unique()) {
|
if (con.unique()) {
|
||||||
constraints += " UNIQUE";
|
constraints += " UNIQUE";
|
||||||
}
|
}
|
||||||
return constraints;
|
return constraints;
|
||||||
|
|||||||
@@ -2,40 +2,41 @@
|
|||||||
// Reflection-based annotation processor.
|
// Reflection-based annotation processor.
|
||||||
// {Args: annotations.database.Member}
|
// {Args: annotations.database.Member}
|
||||||
package annotations.database;
|
package annotations.database;
|
||||||
|
|
||||||
import java.lang.annotation.*;
|
import java.lang.annotation.*;
|
||||||
import java.lang.reflect.*;
|
import java.lang.reflect.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class TableCreator {
|
public class TableCreator {
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
if(args.length < 1) {
|
if (args.length < 1) {
|
||||||
System.out.println("arguments: annotated classes");
|
System.out.println("arguments: annotated classes");
|
||||||
System.exit(0);
|
System.exit(0);
|
||||||
}
|
}
|
||||||
for(String className : args) {
|
for (String className : args) {
|
||||||
Class<?> cl = Class.forName(className);
|
Class<?> cl = Class.forName(className);
|
||||||
DBTable dbTable = cl.getAnnotation(DBTable.class);
|
DBTable dbTable = cl.getAnnotation(DBTable.class);
|
||||||
if(dbTable == null) {
|
if (dbTable == null) {
|
||||||
System.out.println(
|
System.out.println(
|
||||||
"No DBTable annotations in class " + className);
|
"No DBTable annotations in class " + className);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
String tableName = dbTable.name();
|
String tableName = dbTable.name();
|
||||||
// If the name is empty, use the Class name:
|
// If the name is empty, use the Class name:
|
||||||
if(tableName.length() < 1) {
|
if (tableName.length() < 1) {
|
||||||
tableName = cl.getName().toUpperCase();
|
tableName = cl.getName().toUpperCase();
|
||||||
}
|
}
|
||||||
List<String> columnDefs = new ArrayList<String>();
|
List<String> columnDefs = new ArrayList<String>();
|
||||||
for(Field field : cl.getDeclaredFields()) {
|
for (Field field : cl.getDeclaredFields()) {
|
||||||
String columnName = null;
|
String columnName = null;
|
||||||
Annotation[] anns = field.getDeclaredAnnotations();
|
Annotation[] anns = field.getDeclaredAnnotations();
|
||||||
if(anns.length < 1) {
|
if (anns.length < 1) {
|
||||||
continue; // Not a db table column
|
continue; // Not a db table column
|
||||||
}
|
}
|
||||||
if(anns[0] instanceof SQLInteger) {
|
if (anns[0] instanceof SQLInteger) {
|
||||||
SQLInteger sInt = (SQLInteger) anns[0];
|
SQLInteger sInt = (SQLInteger) anns[0];
|
||||||
// Use field name if name not specified
|
// Use field name if name not specified
|
||||||
if(sInt.name().length() < 1) {
|
if (sInt.name().length() < 1) {
|
||||||
columnName = field.getName().toUpperCase();
|
columnName = field.getName().toUpperCase();
|
||||||
} else {
|
} else {
|
||||||
columnName = sInt.name();
|
columnName = sInt.name();
|
||||||
@@ -43,10 +44,10 @@ public class TableCreator {
|
|||||||
columnDefs.add(columnName + " INT" +
|
columnDefs.add(columnName + " INT" +
|
||||||
getConstraints(sInt.constraints()));
|
getConstraints(sInt.constraints()));
|
||||||
}
|
}
|
||||||
if(anns[0] instanceof SQLString) {
|
if (anns[0] instanceof SQLString) {
|
||||||
SQLString sString = (SQLString) anns[0];
|
SQLString sString = (SQLString) anns[0];
|
||||||
// Use field name if name not specified.
|
// Use field name if name not specified.
|
||||||
if(sString.name().length() < 1) {
|
if (sString.name().length() < 1) {
|
||||||
columnName = field.getName().toUpperCase();
|
columnName = field.getName().toUpperCase();
|
||||||
} else {
|
} else {
|
||||||
columnName = sString.name();
|
columnName = sString.name();
|
||||||
@@ -57,7 +58,7 @@ public class TableCreator {
|
|||||||
}
|
}
|
||||||
StringBuilder createCommand = new StringBuilder(
|
StringBuilder createCommand = new StringBuilder(
|
||||||
"CREATE TABLE " + tableName + "(");
|
"CREATE TABLE " + tableName + "(");
|
||||||
for(String columnDef : columnDefs) {
|
for (String columnDef : columnDefs) {
|
||||||
createCommand.append("\n " + columnDef + ",");
|
createCommand.append("\n " + columnDef + ",");
|
||||||
}
|
}
|
||||||
// Remove trailing comma
|
// Remove trailing comma
|
||||||
@@ -68,15 +69,16 @@ public class TableCreator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getConstraints(Constraints con) {
|
private static String getConstraints(Constraints con) {
|
||||||
String constraints = "";
|
String constraints = "";
|
||||||
if(!con.allowNull()) {
|
if (!con.allowNull()) {
|
||||||
constraints += " NOT NULL";
|
constraints += " NOT NULL";
|
||||||
}
|
}
|
||||||
if(con.primaryKey()) {
|
if (con.primaryKey()) {
|
||||||
constraints += " PRIMARY KEY";
|
constraints += " PRIMARY KEY";
|
||||||
}
|
}
|
||||||
if(con.unique()) {
|
if (con.unique()) {
|
||||||
constraints += " UNIQUE";
|
constraints += " UNIQUE";
|
||||||
}
|
}
|
||||||
return constraints;
|
return constraints;
|
||||||
|
|||||||
@@ -4,5 +4,5 @@ package annotations.database;
|
|||||||
|
|
||||||
public @interface Uniqueness {
|
public @interface Uniqueness {
|
||||||
Constraints constraints()
|
Constraints constraints()
|
||||||
default @Constraints(unique=true);
|
default @Constraints(unique = true);
|
||||||
} ///:~
|
} ///:~
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package arrays;//: arrays/AlphabeticSearch.java
|
package arrays;//: arrays/AlphabeticSearch.java
|
||||||
// Searching with a Comparator.
|
// Searching with a Comparator.
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import net.mindview.util.*;
|
import net.mindview.util.*;
|
||||||
|
|
||||||
public class AlphabeticSearch {
|
public class AlphabeticSearch {
|
||||||
@@ -11,7 +13,7 @@ public class AlphabeticSearch {
|
|||||||
System.out.println(Arrays.toString(sa));
|
System.out.println(Arrays.toString(sa));
|
||||||
int index = Arrays.binarySearch(sa, sa[10],
|
int index = Arrays.binarySearch(sa, sa[10],
|
||||||
String.CASE_INSENSITIVE_ORDER);
|
String.CASE_INSENSITIVE_ORDER);
|
||||||
System.out.println("Index: "+ index + "\n"+ sa[index]);
|
System.out.println("Index: " + index + "\n" + sa[index]);
|
||||||
}
|
}
|
||||||
} /* Output:
|
} /* Output:
|
||||||
[bkIna, cQrGs, cXZJo, dLsmw, eGZMm, EqUCB, gwsqP, hKcxr, HLGEa, HqXum, HxxHv, JMRoE, JmzMs, Mesbt, MNvqe, nyGcF, ogoYW, OneOE, OWZnT, RFJQA, rUkZP, sgqia, slJrL, suEcU, uTpnX, vpfFv, WHkjU, xxEAJ, YNzbr, zDyCy]
|
[bkIna, cQrGs, cXZJo, dLsmw, eGZMm, EqUCB, gwsqP, hKcxr, HLGEa, HqXum, HxxHv, JMRoE, JmzMs, Mesbt, MNvqe, nyGcF, ogoYW, OneOE, OWZnT, RFJQA, rUkZP, sgqia, slJrL, suEcU, uTpnX, vpfFv, WHkjU, xxEAJ, YNzbr, zDyCy]
|
||||||
|
|||||||
@@ -3,10 +3,11 @@ package arrays;//: arrays/ArrayOfGenericType.java
|
|||||||
|
|
||||||
public class ArrayOfGenericType<T> {
|
public class ArrayOfGenericType<T> {
|
||||||
T[] array; // OK
|
T[] array; // OK
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public ArrayOfGenericType(int size) {
|
public ArrayOfGenericType(int size) {
|
||||||
//! array = new T[size]; // Illegal
|
//! array = new T[size]; // Illegal
|
||||||
array = (T[])new Object[size]; // "unchecked" Warning
|
array = (T[]) new Object[size]; // "unchecked" Warning
|
||||||
}
|
}
|
||||||
// Illegal:
|
// Illegal:
|
||||||
//! public <U> U[] makeArray() { return new U[10]; }
|
//! public <U> U[] makeArray() { return new U[10]; }
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package arrays;//: arrays/ArrayOfGenerics.java
|
package arrays;//: arrays/ArrayOfGenerics.java
|
||||||
// It is possible to create arrays of generics.
|
// It is possible to create arrays of generics.
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class ArrayOfGenerics {
|
public class ArrayOfGenerics {
|
||||||
@@ -7,7 +8,7 @@ public class ArrayOfGenerics {
|
|||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
List<String>[] ls;
|
List<String>[] ls;
|
||||||
List[] la = new List[10];
|
List[] la = new List[10];
|
||||||
ls = (List<String>[])la; // "Unchecked" warning
|
ls = (List<String>[]) la; // "Unchecked" warning
|
||||||
ls[0] = new ArrayList<String>();
|
ls[0] = new ArrayList<String>();
|
||||||
// Compile-time checking produces an error:
|
// Compile-time checking produces an error:
|
||||||
//! ls[1] = new ArrayList<Integer>();
|
//! ls[1] = new ArrayList<Integer>();
|
||||||
@@ -21,8 +22,8 @@ public class ArrayOfGenerics {
|
|||||||
// possible to create an array of generics, albeit
|
// possible to create an array of generics, albeit
|
||||||
// with an "unchecked" warning:
|
// with an "unchecked" warning:
|
||||||
List<BerylliumSphere>[] spheres =
|
List<BerylliumSphere>[] spheres =
|
||||||
(List<BerylliumSphere>[])new List[10];
|
(List<BerylliumSphere>[]) new List[10];
|
||||||
for(int i = 0; i < spheres.length; i++) {
|
for (int i = 0; i < spheres.length; i++) {
|
||||||
spheres[i] = new ArrayList<BerylliumSphere>();
|
spheres[i] = new ArrayList<BerylliumSphere>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package arrays;//: arrays/ArrayOptions.java
|
package arrays;//: arrays/ArrayOptions.java
|
||||||
// Initialization & re-assignment of arrays.
|
// Initialization & re-assignment of arrays.
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import static net.mindview.util.Print.*;
|
import static net.mindview.util.Print.*;
|
||||||
|
|
||||||
public class ArrayOptions {
|
public class ArrayOptions {
|
||||||
@@ -12,14 +14,14 @@ public class ArrayOptions {
|
|||||||
// automatically initialized to null:
|
// automatically initialized to null:
|
||||||
print("b: " + Arrays.toString(b));
|
print("b: " + Arrays.toString(b));
|
||||||
BerylliumSphere[] c = new BerylliumSphere[4];
|
BerylliumSphere[] c = new BerylliumSphere[4];
|
||||||
for(int i = 0; i < c.length; i++) {
|
for (int i = 0; i < c.length; i++) {
|
||||||
if(c[i] == null) // Can test for null reference
|
if (c[i] == null) // Can test for null reference
|
||||||
{
|
{
|
||||||
c[i] = new BerylliumSphere();
|
c[i] = new BerylliumSphere();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Aggregate initialization:
|
// Aggregate initialization:
|
||||||
BerylliumSphere[] d = { new BerylliumSphere(),
|
BerylliumSphere[] d = {new BerylliumSphere(),
|
||||||
new BerylliumSphere(), new BerylliumSphere()
|
new BerylliumSphere(), new BerylliumSphere()
|
||||||
};
|
};
|
||||||
// Dynamic aggregate initialization:
|
// Dynamic aggregate initialization:
|
||||||
@@ -41,10 +43,10 @@ public class ArrayOptions {
|
|||||||
// automatically initialized to zero:
|
// automatically initialized to zero:
|
||||||
print("f: " + Arrays.toString(f));
|
print("f: " + Arrays.toString(f));
|
||||||
int[] g = new int[4];
|
int[] g = new int[4];
|
||||||
for(int i = 0; i < g.length; i++) {
|
for (int i = 0; i < g.length; i++) {
|
||||||
g[i] = i*i;
|
g[i] = i * i;
|
||||||
}
|
}
|
||||||
int[] h = { 11, 47, 93 };
|
int[] h = {11, 47, 93};
|
||||||
// Compile error: variable e not initialized:
|
// Compile error: variable e not initialized:
|
||||||
//!print("e.length = " + e.length);
|
//!print("e.length = " + e.length);
|
||||||
print("f.length = " + f.length);
|
print("f.length = " + f.length);
|
||||||
@@ -52,7 +54,7 @@ public class ArrayOptions {
|
|||||||
print("h.length = " + h.length);
|
print("h.length = " + h.length);
|
||||||
e = h;
|
e = h;
|
||||||
print("e.length = " + e.length);
|
print("e.length = " + e.length);
|
||||||
e = new int[]{ 1, 2 };
|
e = new int[]{1, 2};
|
||||||
print("e.length = " + e.length);
|
print("e.length = " + e.length);
|
||||||
}
|
}
|
||||||
} /* Output:
|
} /* Output:
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
package arrays;//: arrays/ArraySearching.java
|
package arrays;//: arrays/ArraySearching.java
|
||||||
// Using Arrays.binarySearch().
|
// Using Arrays.binarySearch().
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import net.mindview.util.*;
|
import net.mindview.util.*;
|
||||||
|
|
||||||
import static net.mindview.util.Print.*;
|
import static net.mindview.util.Print.*;
|
||||||
|
|
||||||
public class ArraySearching {
|
public class ArraySearching {
|
||||||
@@ -12,10 +15,10 @@ public class ArraySearching {
|
|||||||
Generated.array(new Integer[25], gen));
|
Generated.array(new Integer[25], gen));
|
||||||
Arrays.sort(a);
|
Arrays.sort(a);
|
||||||
print("Sorted array: " + Arrays.toString(a));
|
print("Sorted array: " + Arrays.toString(a));
|
||||||
while(true) {
|
while (true) {
|
||||||
int r = gen.next();
|
int r = gen.next();
|
||||||
int location = Arrays.binarySearch(a, r);
|
int location = Arrays.binarySearch(a, r);
|
||||||
if(location >= 0) {
|
if (location >= 0) {
|
||||||
print("Location of " + r + " is " + location +
|
print("Location of " + r + " is " + location +
|
||||||
", a[" + location + "] = " + a[location]);
|
", a[" + location + "] = " + a[location]);
|
||||||
break; // Out of while loop
|
break; // Out of while loop
|
||||||
|
|||||||
@@ -1,14 +1,15 @@
|
|||||||
package arrays;//: arrays/AssemblingMultidimensionalArrays.java
|
package arrays;//: arrays/AssemblingMultidimensionalArrays.java
|
||||||
// Creating multidimensional arrays.
|
// Creating multidimensional arrays.
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class AssemblingMultidimensionalArrays {
|
public class AssemblingMultidimensionalArrays {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
Integer[][] a;
|
Integer[][] a;
|
||||||
a = new Integer[3][];
|
a = new Integer[3][];
|
||||||
for(int i = 0; i < a.length; i++) {
|
for (int i = 0; i < a.length; i++) {
|
||||||
a[i] = new Integer[3];
|
a[i] = new Integer[3];
|
||||||
for(int j = 0; j < a[i].length; j++) {
|
for (int j = 0; j < a[i].length; j++) {
|
||||||
a[i][j] = i * j; // Autoboxing
|
a[i][j] = i * j; // Autoboxing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
package arrays;//: arrays/AutoboxingArrays.java
|
package arrays;//: arrays/AutoboxingArrays.java
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class AutoboxingArrays {
|
public class AutoboxingArrays {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
Integer[][] a = { // Autoboxing:
|
Integer[][] a = { // Autoboxing:
|
||||||
{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 },
|
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
|
||||||
{ 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 },
|
{21, 22, 23, 24, 25, 26, 27, 28, 29, 30},
|
||||||
{ 51, 52, 53, 54, 55, 56, 57, 58, 59, 60 },
|
{51, 52, 53, 54, 55, 56, 57, 58, 59, 60},
|
||||||
{ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80 },
|
{71, 72, 73, 74, 75, 76, 77, 78, 79, 80},
|
||||||
};
|
};
|
||||||
System.out.println(Arrays.deepToString(a));
|
System.out.println(Arrays.deepToString(a));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,35 +1,47 @@
|
|||||||
package arrays;//: arrays/CompType.java
|
package arrays;//: arrays/CompType.java
|
||||||
// Implementing Comparable in a class.
|
// Implementing Comparable in a class.
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import net.mindview.util.*;
|
import net.mindview.util.*;
|
||||||
|
|
||||||
import static net.mindview.util.Print.*;
|
import static net.mindview.util.Print.*;
|
||||||
|
|
||||||
public class CompType implements Comparable<CompType> {
|
public class CompType implements Comparable<CompType> {
|
||||||
int i;
|
int i;
|
||||||
int j;
|
int j;
|
||||||
private static int count = 1;
|
private static int count = 1;
|
||||||
|
|
||||||
public CompType(int n1, int n2) {
|
public CompType(int n1, int n2) {
|
||||||
i = n1;
|
i = n1;
|
||||||
j = n2;
|
j = n2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
String result = "[i = " + i + ", j = " + j + "]";
|
String result = "[i = " + i + ", j = " + j + "]";
|
||||||
if(count++ % 3 == 0) {
|
if (count++ % 3 == 0) {
|
||||||
result += "\n";
|
result += "\n";
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int compareTo(CompType rv) {
|
public int compareTo(CompType rv) {
|
||||||
return (i < rv.i ? -1 : (i == rv.i ? 0 : 1));
|
return (i < rv.i ? -1 : (i == rv.i ? 0 : 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Random r = new Random(47);
|
private static Random r = new Random(47);
|
||||||
|
|
||||||
public static Generator<CompType> generator() {
|
public static Generator<CompType> generator() {
|
||||||
return new Generator<CompType>() {
|
return new Generator<CompType>() {
|
||||||
|
@Override
|
||||||
public CompType next() {
|
public CompType next() {
|
||||||
return new CompType(r.nextInt(100),r.nextInt(100));
|
return new CompType(r.nextInt(100), r.nextInt(100));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
CompType[] a =
|
CompType[] a =
|
||||||
Generated.array(new CompType[12], generator());
|
Generated.array(new CompType[12], generator());
|
||||||
|
|||||||
@@ -1,10 +1,14 @@
|
|||||||
package arrays;//: arrays/ComparatorTest.java
|
package arrays;//: arrays/ComparatorTest.java
|
||||||
// Implementing a Comparator for a class.
|
// Implementing a Comparator for a class.
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import net.mindview.util.*;
|
import net.mindview.util.*;
|
||||||
|
|
||||||
import static net.mindview.util.Print.*;
|
import static net.mindview.util.Print.*;
|
||||||
|
|
||||||
class CompTypeComparator implements Comparator<CompType> {
|
class CompTypeComparator implements Comparator<CompType> {
|
||||||
|
@Override
|
||||||
public int compare(CompType o1, CompType o2) {
|
public int compare(CompType o1, CompType o2) {
|
||||||
return (o1.j < o2.j ? -1 : (o1.j == o2.j ? 0 : 1));
|
return (o1.j < o2.j ? -1 : (o1.j == o2.j ? 0 : 1));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package arrays;//: arrays/ComparingArrays.java
|
package arrays;//: arrays/ComparingArrays.java
|
||||||
// Using Arrays.equals()
|
// Using Arrays.equals()
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import static net.mindview.util.Print.*;
|
import static net.mindview.util.Print.*;
|
||||||
|
|
||||||
public class ComparingArrays {
|
public class ComparingArrays {
|
||||||
@@ -14,8 +16,8 @@ public class ComparingArrays {
|
|||||||
print(Arrays.equals(a1, a2));
|
print(Arrays.equals(a1, a2));
|
||||||
String[] s1 = new String[4];
|
String[] s1 = new String[4];
|
||||||
Arrays.fill(s1, "Hi");
|
Arrays.fill(s1, "Hi");
|
||||||
String[] s2 = { new String("Hi"), new String("Hi"),
|
String[] s2 = {new String("Hi"), new String("Hi"),
|
||||||
new String("Hi"), new String("Hi") };
|
new String("Hi"), new String("Hi")};
|
||||||
print(Arrays.equals(s1, s2));
|
print(Arrays.equals(s1, s2));
|
||||||
}
|
}
|
||||||
} /* Output:
|
} /* Output:
|
||||||
|
|||||||
@@ -1,17 +1,23 @@
|
|||||||
package arrays;//: arrays/ContainerComparison.java
|
package arrays;//: arrays/ContainerComparison.java
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import static net.mindview.util.Print.*;
|
import static net.mindview.util.Print.*;
|
||||||
|
|
||||||
class BerylliumSphere {
|
class BerylliumSphere {
|
||||||
private static long counter;
|
private static long counter;
|
||||||
private final long id = counter++;
|
private final long id = counter++;
|
||||||
public String toString() { return "Sphere " + id; }
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Sphere " + id;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ContainerComparison {
|
public class ContainerComparison {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
BerylliumSphere[] spheres = new BerylliumSphere[10];
|
BerylliumSphere[] spheres = new BerylliumSphere[10];
|
||||||
for(int i = 0; i < 5; i++) {
|
for (int i = 0; i < 5; i++) {
|
||||||
spheres[i] = new BerylliumSphere();
|
spheres[i] = new BerylliumSphere();
|
||||||
}
|
}
|
||||||
print(Arrays.toString(spheres));
|
print(Arrays.toString(spheres));
|
||||||
@@ -19,13 +25,13 @@ public class ContainerComparison {
|
|||||||
|
|
||||||
List<BerylliumSphere> sphereList =
|
List<BerylliumSphere> sphereList =
|
||||||
new ArrayList<BerylliumSphere>();
|
new ArrayList<BerylliumSphere>();
|
||||||
for(int i = 0; i < 5; i++) {
|
for (int i = 0; i < 5; i++) {
|
||||||
sphereList.add(new BerylliumSphere());
|
sphereList.add(new BerylliumSphere());
|
||||||
}
|
}
|
||||||
print(sphereList);
|
print(sphereList);
|
||||||
print(sphereList.get(4));
|
print(sphereList.get(4));
|
||||||
|
|
||||||
int[] integers = { 0, 1, 2, 3, 4, 5 };
|
int[] integers = {0, 1, 2, 3, 4, 5};
|
||||||
print(Arrays.toString(integers));
|
print(Arrays.toString(integers));
|
||||||
print(integers[4]);
|
print(integers[4]);
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package arrays;//: arrays/CopyingArrays.java
|
package arrays;//: arrays/CopyingArrays.java
|
||||||
// Using System.arraycopy()
|
// Using System.arraycopy()
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import static net.mindview.util.Print.*;
|
import static net.mindview.util.Print.*;
|
||||||
|
|
||||||
public class CopyingArrays {
|
public class CopyingArrays {
|
||||||
@@ -27,7 +29,7 @@ public class CopyingArrays {
|
|||||||
Arrays.fill(v, new Integer(99));
|
Arrays.fill(v, new Integer(99));
|
||||||
print("u = " + Arrays.toString(u));
|
print("u = " + Arrays.toString(u));
|
||||||
print("v = " + Arrays.toString(v));
|
print("v = " + Arrays.toString(v));
|
||||||
System.arraycopy(v, 0, u, u.length/2, v.length);
|
System.arraycopy(v, 0, u, u.length / 2, v.length);
|
||||||
print("u = " + Arrays.toString(u));
|
print("u = " + Arrays.toString(u));
|
||||||
}
|
}
|
||||||
} /* Output:
|
} /* Output:
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package arrays;//: arrays/FillingArrays.java
|
package arrays;//: arrays/FillingArrays.java
|
||||||
// Using Arrays.fill()
|
// Using Arrays.fill()
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import static net.mindview.util.Print.*;
|
import static net.mindview.util.Print.*;
|
||||||
|
|
||||||
public class FillingArrays {
|
public class FillingArrays {
|
||||||
@@ -17,11 +19,11 @@ public class FillingArrays {
|
|||||||
String[] a9 = new String[size];
|
String[] a9 = new String[size];
|
||||||
Arrays.fill(a1, true);
|
Arrays.fill(a1, true);
|
||||||
print("a1 = " + Arrays.toString(a1));
|
print("a1 = " + Arrays.toString(a1));
|
||||||
Arrays.fill(a2, (byte)11);
|
Arrays.fill(a2, (byte) 11);
|
||||||
print("a2 = " + Arrays.toString(a2));
|
print("a2 = " + Arrays.toString(a2));
|
||||||
Arrays.fill(a3, 'x');
|
Arrays.fill(a3, 'x');
|
||||||
print("a3 = " + Arrays.toString(a3));
|
print("a3 = " + Arrays.toString(a3));
|
||||||
Arrays.fill(a4, (short)17);
|
Arrays.fill(a4, (short) 17);
|
||||||
print("a4 = " + Arrays.toString(a4));
|
print("a4 = " + Arrays.toString(a4));
|
||||||
Arrays.fill(a5, 19);
|
Arrays.fill(a5, 19);
|
||||||
print("a5 = " + Arrays.toString(a5));
|
print("a5 = " + Arrays.toString(a5));
|
||||||
|
|||||||
@@ -1,22 +1,25 @@
|
|||||||
package arrays;//: arrays/GeneratorsTest.java
|
package arrays;//: arrays/GeneratorsTest.java
|
||||||
|
|
||||||
import net.mindview.util.*;
|
import net.mindview.util.*;
|
||||||
|
|
||||||
public class GeneratorsTest {
|
public class GeneratorsTest {
|
||||||
public static int size = 10;
|
public static int size = 10;
|
||||||
|
|
||||||
public static void test(Class<?> surroundingClass) {
|
public static void test(Class<?> surroundingClass) {
|
||||||
for(Class<?> type : surroundingClass.getClasses()) {
|
for (Class<?> type : surroundingClass.getClasses()) {
|
||||||
System.out.print(type.getSimpleName() + ": ");
|
System.out.print(type.getSimpleName() + ": ");
|
||||||
try {
|
try {
|
||||||
Generator<?> g = (Generator<?>)type.newInstance();
|
Generator<?> g = (Generator<?>) type.newInstance();
|
||||||
for(int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
System.out.printf(g.next() + " ");
|
System.out.printf(g.next() + " ");
|
||||||
}
|
}
|
||||||
System.out.println();
|
System.out.println();
|
||||||
} catch(Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
test(CountingGenerator.class);
|
test(CountingGenerator.class);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package arrays;//: arrays/IceCream.java
|
package arrays;//: arrays/IceCream.java
|
||||||
// Returning arrays from methods.
|
// Returning arrays from methods.
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class IceCream {
|
public class IceCream {
|
||||||
@@ -9,25 +10,27 @@ public class IceCream {
|
|||||||
"Mint Chip", "Mocha Almond Fudge", "Rum Raisin",
|
"Mint Chip", "Mocha Almond Fudge", "Rum Raisin",
|
||||||
"Praline Cream", "Mud Pie"
|
"Praline Cream", "Mud Pie"
|
||||||
};
|
};
|
||||||
|
|
||||||
public static String[] flavorSet(int n) {
|
public static String[] flavorSet(int n) {
|
||||||
if(n > FLAVORS.length) {
|
if (n > FLAVORS.length) {
|
||||||
throw new IllegalArgumentException("Set too big");
|
throw new IllegalArgumentException("Set too big");
|
||||||
}
|
}
|
||||||
String[] results = new String[n];
|
String[] results = new String[n];
|
||||||
boolean[] picked = new boolean[FLAVORS.length];
|
boolean[] picked = new boolean[FLAVORS.length];
|
||||||
for(int i = 0; i < n; i++) {
|
for (int i = 0; i < n; i++) {
|
||||||
int t;
|
int t;
|
||||||
do {
|
do {
|
||||||
t = rand.nextInt(FLAVORS.length);
|
t = rand.nextInt(FLAVORS.length);
|
||||||
}
|
}
|
||||||
while(picked[t]);
|
while (picked[t]);
|
||||||
results[i] = FLAVORS[t];
|
results[i] = FLAVORS[t];
|
||||||
picked[t] = true;
|
picked[t] = true;
|
||||||
}
|
}
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
for(int i = 0; i < 7; i++) {
|
for (int i = 0; i < 7; i++) {
|
||||||
System.out.println(Arrays.toString(flavorSet(3)));
|
System.out.println(Arrays.toString(flavorSet(3)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,22 +1,23 @@
|
|||||||
package arrays;//: arrays/MultiDimWrapperArray.java
|
package arrays;//: arrays/MultiDimWrapperArray.java
|
||||||
// Multidimensional arrays of "wrapper" objects.
|
// Multidimensional arrays of "wrapper" objects.
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class MultiDimWrapperArray {
|
public class MultiDimWrapperArray {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
Integer[][] a1 = { // Autoboxing
|
Integer[][] a1 = { // Autoboxing
|
||||||
{ 1, 2, 3, },
|
{1, 2, 3,},
|
||||||
{ 4, 5, 6, },
|
{4, 5, 6,},
|
||||||
};
|
};
|
||||||
Double[][][] a2 = { // Autoboxing
|
Double[][][] a2 = { // Autoboxing
|
||||||
{ { 1.1, 2.2 }, { 3.3, 4.4 } },
|
{{1.1, 2.2}, {3.3, 4.4}},
|
||||||
{ { 5.5, 6.6 }, { 7.7, 8.8 } },
|
{{5.5, 6.6}, {7.7, 8.8}},
|
||||||
{ { 9.9, 1.2 }, { 2.3, 3.4 } },
|
{{9.9, 1.2}, {2.3, 3.4}},
|
||||||
};
|
};
|
||||||
String[][] a3 = {
|
String[][] a3 = {
|
||||||
{ "The", "Quick", "Sly", "Fox" },
|
{"The", "Quick", "Sly", "Fox"},
|
||||||
{ "Jumped", "Over" },
|
{"Jumped", "Over"},
|
||||||
{ "The", "Lazy", "Brown", "Dog", "and", "friend" },
|
{"The", "Lazy", "Brown", "Dog", "and", "friend"},
|
||||||
};
|
};
|
||||||
System.out.println("a1: " + Arrays.deepToString(a1));
|
System.out.println("a1: " + Arrays.deepToString(a1));
|
||||||
System.out.println("a2: " + Arrays.deepToString(a2));
|
System.out.println("a2: " + Arrays.deepToString(a2));
|
||||||
|
|||||||
@@ -1,16 +1,17 @@
|
|||||||
package arrays;//: arrays/MultidimensionalObjectArrays.java
|
package arrays;//: arrays/MultidimensionalObjectArrays.java
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class MultidimensionalObjectArrays {
|
public class MultidimensionalObjectArrays {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
BerylliumSphere[][] spheres = {
|
BerylliumSphere[][] spheres = {
|
||||||
{ new BerylliumSphere(), new BerylliumSphere() },
|
{new BerylliumSphere(), new BerylliumSphere()},
|
||||||
{ new BerylliumSphere(), new BerylliumSphere(),
|
{new BerylliumSphere(), new BerylliumSphere(),
|
||||||
new BerylliumSphere(), new BerylliumSphere() },
|
new BerylliumSphere(), new BerylliumSphere()},
|
||||||
{ new BerylliumSphere(), new BerylliumSphere(),
|
{new BerylliumSphere(), new BerylliumSphere(),
|
||||||
new BerylliumSphere(), new BerylliumSphere(),
|
new BerylliumSphere(), new BerylliumSphere(),
|
||||||
new BerylliumSphere(), new BerylliumSphere(),
|
new BerylliumSphere(), new BerylliumSphere(),
|
||||||
new BerylliumSphere(), new BerylliumSphere() },
|
new BerylliumSphere(), new BerylliumSphere()},
|
||||||
};
|
};
|
||||||
System.out.println(Arrays.deepToString(spheres));
|
System.out.println(Arrays.deepToString(spheres));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
package arrays;//: arrays/MultidimensionalPrimitiveArray.java
|
package arrays;//: arrays/MultidimensionalPrimitiveArray.java
|
||||||
// Creating multidimensional arrays.
|
// Creating multidimensional arrays.
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class MultidimensionalPrimitiveArray {
|
public class MultidimensionalPrimitiveArray {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
int[][] a = {
|
int[][] a = {
|
||||||
{ 1, 2, 3, },
|
{1, 2, 3,},
|
||||||
{ 4, 5, 6, },
|
{4, 5, 6,},
|
||||||
};
|
};
|
||||||
System.out.println(Arrays.deepToString(a));
|
System.out.println(Arrays.deepToString(a));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,21 @@
|
|||||||
package arrays;//: arrays/ParameterizedArrayType.java
|
package arrays;//: arrays/ParameterizedArrayType.java
|
||||||
|
|
||||||
class ClassParameter<T> {
|
class ClassParameter<T> {
|
||||||
public T[] f(T[] arg) { return arg; }
|
public T[] f(T[] arg) {
|
||||||
|
return arg;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class MethodParameter {
|
class MethodParameter {
|
||||||
public static <T> T[] f(T[] arg) { return arg; }
|
public static <T> T[] f(T[] arg) {
|
||||||
|
return arg;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ParameterizedArrayType {
|
public class ParameterizedArrayType {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
Integer[] ints = { 1, 2, 3, 4, 5 };
|
Integer[] ints = {1, 2, 3, 4, 5};
|
||||||
Double[] doubles = { 1.1, 2.2, 3.3, 4.4, 5.5 };
|
Double[] doubles = {1.1, 2.2, 3.3, 4.4, 5.5};
|
||||||
Integer[] ints2 =
|
Integer[] ints2 =
|
||||||
new ClassParameter<Integer>().f(ints);
|
new ClassParameter<Integer>().f(ints);
|
||||||
Double[] doubles2 =
|
Double[] doubles2 =
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package arrays;//: arrays/PrimitiveConversionDemonstration.java
|
package arrays;//: arrays/PrimitiveConversionDemonstration.java
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import net.mindview.util.*;
|
import net.mindview.util.*;
|
||||||
|
|
||||||
public class PrimitiveConversionDemonstration {
|
public class PrimitiveConversionDemonstration {
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
package arrays;//: arrays/RaggedArray.java
|
package arrays;//: arrays/RaggedArray.java
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class RaggedArray {
|
public class RaggedArray {
|
||||||
@@ -6,9 +7,9 @@ public class RaggedArray {
|
|||||||
Random rand = new Random(47);
|
Random rand = new Random(47);
|
||||||
// 3-D array with varied-length vectors:
|
// 3-D array with varied-length vectors:
|
||||||
int[][][] a = new int[rand.nextInt(7)][][];
|
int[][][] a = new int[rand.nextInt(7)][][];
|
||||||
for(int i = 0; i < a.length; i++) {
|
for (int i = 0; i < a.length; i++) {
|
||||||
a[i] = new int[rand.nextInt(5)][];
|
a[i] = new int[rand.nextInt(5)][];
|
||||||
for(int j = 0; j < a[i].length; j++) {
|
for (int j = 0; j < a[i].length; j++) {
|
||||||
a[i][j] = new int[rand.nextInt(5)];
|
a[i][j] = new int[rand.nextInt(5)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
package arrays;//: arrays/RandomGeneratorsTest.java
|
package arrays;//: arrays/RandomGeneratorsTest.java
|
||||||
|
|
||||||
import net.mindview.util.*;
|
import net.mindview.util.*;
|
||||||
|
|
||||||
public class RandomGeneratorsTest {
|
public class RandomGeneratorsTest {
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
package arrays;//: arrays/Reverse.java
|
package arrays;//: arrays/Reverse.java
|
||||||
// The Collections.reverseOrder() Comparator
|
// The Collections.reverseOrder() Comparator
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import net.mindview.util.*;
|
import net.mindview.util.*;
|
||||||
|
|
||||||
import static net.mindview.util.Print.*;
|
import static net.mindview.util.Print.*;
|
||||||
|
|
||||||
public class Reverse {
|
public class Reverse {
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
package arrays;//: arrays/StringSorting.java
|
package arrays;//: arrays/StringSorting.java
|
||||||
// Sorting an array of Strings.
|
// Sorting an array of Strings.
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import net.mindview.util.*;
|
import net.mindview.util.*;
|
||||||
|
|
||||||
import static net.mindview.util.Print.*;
|
import static net.mindview.util.Print.*;
|
||||||
|
|
||||||
public class StringSorting {
|
public class StringSorting {
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
package arrays;//: arrays/TestArrayGeneration.java
|
package arrays;//: arrays/TestArrayGeneration.java
|
||||||
// Test the tools that use generators to fill arrays.
|
// Test the tools that use generators to fill arrays.
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import net.mindview.util.*;
|
import net.mindview.util.*;
|
||||||
|
|
||||||
import static net.mindview.util.Print.*;
|
import static net.mindview.util.Print.*;
|
||||||
|
|
||||||
public class TestArrayGeneration {
|
public class TestArrayGeneration {
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
package arrays;//: arrays/TestGenerated.java
|
package arrays;//: arrays/TestGenerated.java
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import net.mindview.util.*;
|
import net.mindview.util.*;
|
||||||
|
|
||||||
public class TestGenerated {
|
public class TestGenerated {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
Integer[] a = { 9, 8, 7, 6 };
|
Integer[] a = {9, 8, 7, 6};
|
||||||
System.out.println(Arrays.toString(a));
|
System.out.println(Arrays.toString(a));
|
||||||
a = Generated.array(a,new CountingGenerator.Integer());
|
a = Generated.array(a, new CountingGenerator.Integer());
|
||||||
System.out.println(Arrays.toString(a));
|
System.out.println(Arrays.toString(a));
|
||||||
Integer[] b = Generated.array(Integer.class,
|
Integer[] b = Generated.array(Integer.class,
|
||||||
new CountingGenerator.Integer(), 15);
|
new CountingGenerator.Integer(), 15);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
package arrays;//: arrays/ThreeDWithNew.java
|
package arrays;//: arrays/ThreeDWithNew.java
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class ThreeDWithNew {
|
public class ThreeDWithNew {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
//: bangbean/BangBean.java
|
//: bangbean/BangBean.java
|
||||||
// A graphical Bean.
|
// A graphical Bean.
|
||||||
package bangbean;
|
package bangbean;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.awt.event.*;
|
import java.awt.event.*;
|
||||||
@@ -15,68 +16,95 @@ BangBean extends JPanel implements Serializable {
|
|||||||
private int fontSize = 48;
|
private int fontSize = 48;
|
||||||
private Color tColor = Color.RED;
|
private Color tColor = Color.RED;
|
||||||
private ActionListener actionListener;
|
private ActionListener actionListener;
|
||||||
|
|
||||||
public BangBean() {
|
public BangBean() {
|
||||||
addMouseListener(new ML());
|
addMouseListener(new ML());
|
||||||
addMouseMotionListener(new MML());
|
addMouseMotionListener(new MML());
|
||||||
}
|
}
|
||||||
public int getCircleSize() { return cSize; }
|
|
||||||
|
public int getCircleSize() {
|
||||||
|
return cSize;
|
||||||
|
}
|
||||||
|
|
||||||
public void setCircleSize(int newSize) {
|
public void setCircleSize(int newSize) {
|
||||||
cSize = newSize;
|
cSize = newSize;
|
||||||
}
|
}
|
||||||
public String getBangText() { return text; }
|
|
||||||
|
public String getBangText() {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
public void setBangText(String newText) {
|
public void setBangText(String newText) {
|
||||||
text = newText;
|
text = newText;
|
||||||
}
|
}
|
||||||
public int getFontSize() { return fontSize; }
|
|
||||||
|
public int getFontSize() {
|
||||||
|
return fontSize;
|
||||||
|
}
|
||||||
|
|
||||||
public void setFontSize(int newSize) {
|
public void setFontSize(int newSize) {
|
||||||
fontSize = newSize;
|
fontSize = newSize;
|
||||||
}
|
}
|
||||||
public Color getTextColor() { return tColor; }
|
|
||||||
|
public Color getTextColor() {
|
||||||
|
return tColor;
|
||||||
|
}
|
||||||
|
|
||||||
public void setTextColor(Color newColor) {
|
public void setTextColor(Color newColor) {
|
||||||
tColor = newColor;
|
tColor = newColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void paintComponent(Graphics g) {
|
public void paintComponent(Graphics g) {
|
||||||
super.paintComponent(g);
|
super.paintComponent(g);
|
||||||
g.setColor(Color.BLACK);
|
g.setColor(Color.BLACK);
|
||||||
g.drawOval(xm - cSize/2, ym - cSize/2, cSize, cSize);
|
g.drawOval(xm - cSize / 2, ym - cSize / 2, cSize, cSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is a unicast listener, which is
|
// This is a unicast listener, which is
|
||||||
// the simplest form of listener management:
|
// the simplest form of listener management:
|
||||||
public void addActionListener(ActionListener l)
|
public void addActionListener(ActionListener l)
|
||||||
throws TooManyListenersException {
|
throws TooManyListenersException {
|
||||||
if(actionListener != null) {
|
if (actionListener != null) {
|
||||||
throw new TooManyListenersException();
|
throw new TooManyListenersException();
|
||||||
}
|
}
|
||||||
actionListener = l;
|
actionListener = l;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeActionListener(ActionListener l) {
|
public void removeActionListener(ActionListener l) {
|
||||||
actionListener = null;
|
actionListener = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
class ML extends MouseAdapter {
|
class ML extends MouseAdapter {
|
||||||
|
@Override
|
||||||
public void mousePressed(MouseEvent e) {
|
public void mousePressed(MouseEvent e) {
|
||||||
Graphics g = getGraphics();
|
Graphics g = getGraphics();
|
||||||
g.setColor(tColor);
|
g.setColor(tColor);
|
||||||
g.setFont(
|
g.setFont(
|
||||||
new Font("TimesRoman", Font.BOLD, fontSize));
|
new Font("TimesRoman", Font.BOLD, fontSize));
|
||||||
int width = g.getFontMetrics().stringWidth(text);
|
int width = g.getFontMetrics().stringWidth(text);
|
||||||
g.drawString(text, (getSize().width - width) /2,
|
g.drawString(text, (getSize().width - width) / 2,
|
||||||
getSize().height/2);
|
getSize().height / 2);
|
||||||
g.dispose();
|
g.dispose();
|
||||||
// Call the listener's method:
|
// Call the listener's method:
|
||||||
if(actionListener != null) {
|
if (actionListener != null) {
|
||||||
actionListener.actionPerformed(
|
actionListener.actionPerformed(
|
||||||
new ActionEvent(BangBean.this,
|
new ActionEvent(BangBean.this,
|
||||||
ActionEvent.ACTION_PERFORMED, null));
|
ActionEvent.ACTION_PERFORMED, null));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class MML extends MouseMotionAdapter {
|
class MML extends MouseMotionAdapter {
|
||||||
|
@Override
|
||||||
public void mouseMoved(MouseEvent e) {
|
public void mouseMoved(MouseEvent e) {
|
||||||
xm = e.getX();
|
xm = e.getX();
|
||||||
ym = e.getY();
|
ym = e.getY();
|
||||||
repaint();
|
repaint();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Dimension getPreferredSize() {
|
public Dimension getPreferredSize() {
|
||||||
return new Dimension(200, 200);
|
return new Dimension(200, 200);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,31 +1,38 @@
|
|||||||
//: bangbean/BangBeanTest.java
|
//: bangbean/BangBeanTest.java
|
||||||
// {Timeout: 5} Abort after 5 seconds when testing
|
// {Timeout: 5} Abort after 5 seconds when testing
|
||||||
package bangbean;
|
package bangbean;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.awt.event.*;
|
import java.awt.event.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import static net.mindview.util.SwingConsole.*;
|
import static net.mindview.util.SwingConsole.*;
|
||||||
|
|
||||||
public class BangBeanTest extends JFrame {
|
public class BangBeanTest extends JFrame {
|
||||||
private JTextField txt = new JTextField(20);
|
private JTextField txt = new JTextField(20);
|
||||||
|
|
||||||
// During testing, report actions:
|
// During testing, report actions:
|
||||||
class BBL implements ActionListener {
|
class BBL implements ActionListener {
|
||||||
private int count = 0;
|
private int count = 0;
|
||||||
|
|
||||||
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
txt.setText("BangBean action "+ count++);
|
txt.setText("BangBean action " + count++);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public BangBeanTest() {
|
public BangBeanTest() {
|
||||||
BangBean bb = new BangBean();
|
BangBean bb = new BangBean();
|
||||||
try {
|
try {
|
||||||
bb.addActionListener(new BBL());
|
bb.addActionListener(new BBL());
|
||||||
} catch(TooManyListenersException e) {
|
} catch (TooManyListenersException e) {
|
||||||
txt.setText("Too many listeners");
|
txt.setText("Too many listeners");
|
||||||
}
|
}
|
||||||
add(bb);
|
add(bb);
|
||||||
add(BorderLayout.SOUTH, txt);
|
add(BorderLayout.SOUTH, txt);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
run(new BangBeanTest(), 400, 500);
|
run(new BangBeanTest(), 400, 500);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,27 +2,32 @@ package concurrency;//: concurrency/ActiveObjectDemo.java
|
|||||||
// Can only pass constants, immutables, "disconnected
|
// Can only pass constants, immutables, "disconnected
|
||||||
// objects," or other active objects as arguments
|
// objects," or other active objects as arguments
|
||||||
// to asynch methods.
|
// to asynch methods.
|
||||||
|
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import static net.mindview.util.Print.*;
|
import static net.mindview.util.Print.*;
|
||||||
|
|
||||||
public class ActiveObjectDemo {
|
public class ActiveObjectDemo {
|
||||||
private ExecutorService ex =
|
private ExecutorService ex =
|
||||||
Executors.newSingleThreadExecutor();
|
Executors.newSingleThreadExecutor();
|
||||||
private Random rand = new Random(47);
|
private Random rand = new Random(47);
|
||||||
|
|
||||||
// Insert a random delay to produce the effect
|
// Insert a random delay to produce the effect
|
||||||
// of a calculation time:
|
// of a calculation time:
|
||||||
private void pause(int factor) {
|
private void pause(int factor) {
|
||||||
try {
|
try {
|
||||||
TimeUnit.MILLISECONDS.sleep(
|
TimeUnit.MILLISECONDS.sleep(
|
||||||
100 + rand.nextInt(factor));
|
100 + rand.nextInt(factor));
|
||||||
} catch(InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
print("sleep() interrupted");
|
print("sleep() interrupted");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Future<Integer>
|
public Future<Integer>
|
||||||
calculateInt(final int x, final int y) {
|
calculateInt(final int x, final int y) {
|
||||||
return ex.submit(new Callable<Integer>() {
|
return ex.submit(new Callable<Integer>() {
|
||||||
|
@Override
|
||||||
public Integer call() {
|
public Integer call() {
|
||||||
print("starting " + x + " + " + y);
|
print("starting " + x + " + " + y);
|
||||||
pause(500);
|
pause(500);
|
||||||
@@ -30,9 +35,11 @@ public class ActiveObjectDemo {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public Future<Float>
|
public Future<Float>
|
||||||
calculateFloat(final float x, final float y) {
|
calculateFloat(final float x, final float y) {
|
||||||
return ex.submit(new Callable<Float>() {
|
return ex.submit(new Callable<Float>() {
|
||||||
|
@Override
|
||||||
public Float call() {
|
public Float call() {
|
||||||
print("starting " + x + " + " + y);
|
print("starting " + x + " + " + y);
|
||||||
pause(2000);
|
pause(2000);
|
||||||
@@ -40,25 +47,29 @@ public class ActiveObjectDemo {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
public void shutdown() { ex.shutdown(); }
|
|
||||||
|
public void shutdown() {
|
||||||
|
ex.shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
ActiveObjectDemo d1 = new ActiveObjectDemo();
|
ActiveObjectDemo d1 = new ActiveObjectDemo();
|
||||||
// Prevents ConcurrentModificationException:
|
// Prevents ConcurrentModificationException:
|
||||||
List<Future<?>> results =
|
List<Future<?>> results =
|
||||||
new CopyOnWriteArrayList<Future<?>>();
|
new CopyOnWriteArrayList<Future<?>>();
|
||||||
for(float f = 0.0f; f < 1.0f; f += 0.2f) {
|
for (float f = 0.0f; f < 1.0f; f += 0.2f) {
|
||||||
results.add(d1.calculateFloat(f, f));
|
results.add(d1.calculateFloat(f, f));
|
||||||
}
|
}
|
||||||
for(int i = 0; i < 5; i++) {
|
for (int i = 0; i < 5; i++) {
|
||||||
results.add(d1.calculateInt(i, i));
|
results.add(d1.calculateInt(i, i));
|
||||||
}
|
}
|
||||||
print("All asynch calls made");
|
print("All asynch calls made");
|
||||||
while(results.size() > 0) {
|
while (results.size() > 0) {
|
||||||
for(Future<?> f : results) {
|
for (Future<?> f : results) {
|
||||||
if(f.isDone()) {
|
if (f.isDone()) {
|
||||||
try {
|
try {
|
||||||
print(f.get());
|
print(f.get());
|
||||||
} catch(Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
results.remove(f);
|
results.remove(f);
|
||||||
|
|||||||
@@ -1,14 +1,18 @@
|
|||||||
package concurrency;//: concurrency/AtomicEvenGenerator.java
|
package concurrency;//: concurrency/AtomicEvenGenerator.java
|
||||||
// Atomic classes are occasionally useful in regular code.
|
// Atomic classes are occasionally useful in regular code.
|
||||||
// {RunByHand}
|
// {RunByHand}
|
||||||
|
|
||||||
import java.util.concurrent.atomic.*;
|
import java.util.concurrent.atomic.*;
|
||||||
|
|
||||||
public class AtomicEvenGenerator extends IntGenerator {
|
public class AtomicEvenGenerator extends IntGenerator {
|
||||||
private AtomicInteger currentEvenValue =
|
private AtomicInteger currentEvenValue =
|
||||||
new AtomicInteger(0);
|
new AtomicInteger(0);
|
||||||
|
|
||||||
|
@Override
|
||||||
public int next() {
|
public int next() {
|
||||||
return currentEvenValue.addAndGet(2);
|
return currentEvenValue.addAndGet(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
EvenChecker.test(new AtomicEvenGenerator());
|
EvenChecker.test(new AtomicEvenGenerator());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +1,30 @@
|
|||||||
package concurrency;//: concurrency/AtomicIntegerTest.java
|
package concurrency;//: concurrency/AtomicIntegerTest.java
|
||||||
|
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
import java.util.concurrent.atomic.*;
|
import java.util.concurrent.atomic.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class AtomicIntegerTest implements Runnable {
|
public class AtomicIntegerTest implements Runnable {
|
||||||
private AtomicInteger i = new AtomicInteger(0);
|
private AtomicInteger i = new AtomicInteger(0);
|
||||||
public int getValue() { return i.get(); }
|
|
||||||
private void evenIncrement() { i.addAndGet(2); }
|
public int getValue() {
|
||||||
|
return i.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void evenIncrement() {
|
||||||
|
i.addAndGet(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
while(true) {
|
while (true) {
|
||||||
evenIncrement();
|
evenIncrement();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
new Timer().schedule(new TimerTask() {
|
new Timer().schedule(new TimerTask() {
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
System.err.println("Aborting");
|
System.err.println("Aborting");
|
||||||
System.exit(0);
|
System.exit(0);
|
||||||
@@ -22,9 +33,9 @@ public class AtomicIntegerTest implements Runnable {
|
|||||||
ExecutorService exec = Executors.newCachedThreadPool();
|
ExecutorService exec = Executors.newCachedThreadPool();
|
||||||
AtomicIntegerTest ait = new AtomicIntegerTest();
|
AtomicIntegerTest ait = new AtomicIntegerTest();
|
||||||
exec.execute(ait);
|
exec.execute(ait);
|
||||||
while(true) {
|
while (true) {
|
||||||
int val = ait.getValue();
|
int val = ait.getValue();
|
||||||
if(val % 2 != 0) {
|
if (val % 2 != 0) {
|
||||||
System.out.println(val);
|
System.out.println(val);
|
||||||
System.exit(0);
|
System.exit(0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,8 +3,14 @@ package concurrency;//: concurrency/Atomicity.java
|
|||||||
|
|
||||||
public class Atomicity {
|
public class Atomicity {
|
||||||
int i;
|
int i;
|
||||||
void f1() { i++; }
|
|
||||||
void f2() { i += 3; }
|
void f1() {
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void f2() {
|
||||||
|
i += 3;
|
||||||
|
}
|
||||||
} /* Output: (Sample)
|
} /* Output: (Sample)
|
||||||
...
|
...
|
||||||
void f1();
|
void f1();
|
||||||
|
|||||||
@@ -1,22 +1,33 @@
|
|||||||
package concurrency;//: concurrency/AtomicityTest.java
|
package concurrency;//: concurrency/AtomicityTest.java
|
||||||
|
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
|
|
||||||
public class AtomicityTest implements Runnable {
|
public class AtomicityTest implements Runnable {
|
||||||
private int i = 0;
|
private int i = 0;
|
||||||
public int getValue() { return i; }
|
|
||||||
private synchronized void evenIncrement() { i++; i++; }
|
public int getValue() {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
private synchronized void evenIncrement() {
|
||||||
|
i++;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
while(true) {
|
while (true) {
|
||||||
evenIncrement();
|
evenIncrement();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
ExecutorService exec = Executors.newCachedThreadPool();
|
ExecutorService exec = Executors.newCachedThreadPool();
|
||||||
AtomicityTest at = new AtomicityTest();
|
AtomicityTest at = new AtomicityTest();
|
||||||
exec.execute(at);
|
exec.execute(at);
|
||||||
while(true) {
|
while (true) {
|
||||||
int val = at.getValue();
|
int val = at.getValue();
|
||||||
if(val % 2 != 0) {
|
if (val % 2 != 0) {
|
||||||
System.out.println(val);
|
System.out.println(val);
|
||||||
System.exit(0);
|
System.exit(0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,44 +1,52 @@
|
|||||||
package concurrency;//: concurrency/AttemptLocking.java
|
package concurrency;//: concurrency/AttemptLocking.java
|
||||||
// Locks in the concurrent library allow you
|
// Locks in the concurrent library allow you
|
||||||
// to give up on trying to acquire a lock.
|
// to give up on trying to acquire a lock.
|
||||||
|
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
import java.util.concurrent.locks.*;
|
import java.util.concurrent.locks.*;
|
||||||
|
|
||||||
public class AttemptLocking {
|
public class AttemptLocking {
|
||||||
private ReentrantLock lock = new ReentrantLock();
|
private ReentrantLock lock = new ReentrantLock();
|
||||||
|
|
||||||
public void untimed() {
|
public void untimed() {
|
||||||
boolean captured = lock.tryLock();
|
boolean captured = lock.tryLock();
|
||||||
try {
|
try {
|
||||||
System.out.println("tryLock(): " + captured);
|
System.out.println("tryLock(): " + captured);
|
||||||
} finally {
|
} finally {
|
||||||
if(captured) {
|
if (captured) {
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void timed() {
|
public void timed() {
|
||||||
boolean captured = false;
|
boolean captured = false;
|
||||||
try {
|
try {
|
||||||
captured = lock.tryLock(2, TimeUnit.SECONDS);
|
captured = lock.tryLock(2, TimeUnit.SECONDS);
|
||||||
} catch(InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
System.out.println("tryLock(2, TimeUnit.SECONDS): " +
|
System.out.println("tryLock(2, TimeUnit.SECONDS): " +
|
||||||
captured);
|
captured);
|
||||||
} finally {
|
} finally {
|
||||||
if(captured) {
|
if (captured) {
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
final AttemptLocking al = new AttemptLocking();
|
final AttemptLocking al = new AttemptLocking();
|
||||||
al.untimed(); // True -- lock is available
|
al.untimed(); // True -- lock is available
|
||||||
al.timed(); // True -- lock is available
|
al.timed(); // True -- lock is available
|
||||||
// Now create a separate task to grab the lock:
|
// Now create a separate task to grab the lock:
|
||||||
new Thread() {
|
new Thread() {
|
||||||
{ setDaemon(true); }
|
{
|
||||||
|
setDaemon(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
al.lock.lock();
|
al.lock.lock();
|
||||||
System.out.println("acquired");
|
System.out.println("acquired");
|
||||||
|
|||||||
@@ -1,14 +1,23 @@
|
|||||||
package concurrency;//: concurrency/BankTellerSimulation.java
|
package concurrency;//: concurrency/BankTellerSimulation.java
|
||||||
// Using queues and multithreading.
|
// Using queues and multithreading.
|
||||||
// {Args: 5}
|
// {Args: 5}
|
||||||
|
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
// Read-only objects don't require synchronization:
|
// Read-only objects don't require synchronization:
|
||||||
class Customer {
|
class Customer {
|
||||||
private final int serviceTime;
|
private final int serviceTime;
|
||||||
public Customer(int tm) { serviceTime = tm; }
|
|
||||||
public int getServiceTime() { return serviceTime; }
|
public Customer(int tm) {
|
||||||
|
serviceTime = tm;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getServiceTime() {
|
||||||
|
return serviceTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "[" + serviceTime + "]";
|
return "[" + serviceTime + "]";
|
||||||
}
|
}
|
||||||
@@ -19,12 +28,14 @@ class CustomerLine extends ArrayBlockingQueue<Customer> {
|
|||||||
public CustomerLine(int maxLineSize) {
|
public CustomerLine(int maxLineSize) {
|
||||||
super(maxLineSize);
|
super(maxLineSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
if(this.size() == 0) {
|
if (this.size() == 0) {
|
||||||
return "[Empty]";
|
return "[Empty]";
|
||||||
}
|
}
|
||||||
StringBuilder result = new StringBuilder();
|
StringBuilder result = new StringBuilder();
|
||||||
for(Customer customer : this) {
|
for (Customer customer : this) {
|
||||||
result.append(customer);
|
result.append(customer);
|
||||||
}
|
}
|
||||||
return result.toString();
|
return result.toString();
|
||||||
@@ -35,16 +46,19 @@ class CustomerLine extends ArrayBlockingQueue<Customer> {
|
|||||||
class CustomerGenerator implements Runnable {
|
class CustomerGenerator implements Runnable {
|
||||||
private CustomerLine customers;
|
private CustomerLine customers;
|
||||||
private static Random rand = new Random(47);
|
private static Random rand = new Random(47);
|
||||||
|
|
||||||
public CustomerGenerator(CustomerLine cq) {
|
public CustomerGenerator(CustomerLine cq) {
|
||||||
customers = cq;
|
customers = cq;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
while(!Thread.interrupted()) {
|
while (!Thread.interrupted()) {
|
||||||
TimeUnit.MILLISECONDS.sleep(rand.nextInt(300));
|
TimeUnit.MILLISECONDS.sleep(rand.nextInt(300));
|
||||||
customers.put(new Customer(rand.nextInt(1000)));
|
customers.put(new Customer(rand.nextInt(1000)));
|
||||||
}
|
}
|
||||||
} catch(InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
System.out.println("CustomerGenerator interrupted");
|
System.out.println("CustomerGenerator interrupted");
|
||||||
}
|
}
|
||||||
System.out.println("CustomerGenerator terminating");
|
System.out.println("CustomerGenerator terminating");
|
||||||
@@ -58,37 +72,53 @@ class Teller implements Runnable, Comparable<Teller> {
|
|||||||
private int customersServed = 0;
|
private int customersServed = 0;
|
||||||
private CustomerLine customers;
|
private CustomerLine customers;
|
||||||
private boolean servingCustomerLine = true;
|
private boolean servingCustomerLine = true;
|
||||||
public Teller(CustomerLine cq) { customers = cq; }
|
|
||||||
|
public Teller(CustomerLine cq) {
|
||||||
|
customers = cq;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
while(!Thread.interrupted()) {
|
while (!Thread.interrupted()) {
|
||||||
Customer customer = customers.take();
|
Customer customer = customers.take();
|
||||||
TimeUnit.MILLISECONDS.sleep(
|
TimeUnit.MILLISECONDS.sleep(
|
||||||
customer.getServiceTime());
|
customer.getServiceTime());
|
||||||
synchronized(this) {
|
synchronized (this) {
|
||||||
customersServed++;
|
customersServed++;
|
||||||
while(!servingCustomerLine) {
|
while (!servingCustomerLine) {
|
||||||
wait();
|
wait();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch(InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
System.out.println(this + "interrupted");
|
System.out.println(this + "interrupted");
|
||||||
}
|
}
|
||||||
System.out.println(this + "terminating");
|
System.out.println(this + "terminating");
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void doSomethingElse() {
|
public synchronized void doSomethingElse() {
|
||||||
customersServed = 0;
|
customersServed = 0;
|
||||||
servingCustomerLine = false;
|
servingCustomerLine = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void serveCustomerLine() {
|
public synchronized void serveCustomerLine() {
|
||||||
assert !servingCustomerLine:"already serving: " + this;
|
assert !servingCustomerLine : "already serving: " + this;
|
||||||
servingCustomerLine = true;
|
servingCustomerLine = true;
|
||||||
notifyAll();
|
notifyAll();
|
||||||
}
|
}
|
||||||
public String toString() { return "Teller " + id + " "; }
|
|
||||||
public String shortString() { return "T" + id; }
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Teller " + id + " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String shortString() {
|
||||||
|
return "T" + id;
|
||||||
|
}
|
||||||
|
|
||||||
// Used by priority queue:
|
// Used by priority queue:
|
||||||
|
@Override
|
||||||
public synchronized int compareTo(Teller other) {
|
public synchronized int compareTo(Teller other) {
|
||||||
return customersServed < other.customersServed ? -1 :
|
return customersServed < other.customersServed ? -1 :
|
||||||
(customersServed == other.customersServed ? 0 : 1);
|
(customersServed == other.customersServed ? 0 : 1);
|
||||||
@@ -104,6 +134,7 @@ class TellerManager implements Runnable {
|
|||||||
new LinkedList<Teller>();
|
new LinkedList<Teller>();
|
||||||
private int adjustmentPeriod;
|
private int adjustmentPeriod;
|
||||||
private static Random rand = new Random(47);
|
private static Random rand = new Random(47);
|
||||||
|
|
||||||
public TellerManager(ExecutorService e,
|
public TellerManager(ExecutorService e,
|
||||||
CustomerLine customers, int adjustmentPeriod) {
|
CustomerLine customers, int adjustmentPeriod) {
|
||||||
exec = e;
|
exec = e;
|
||||||
@@ -114,15 +145,16 @@ class TellerManager implements Runnable {
|
|||||||
exec.execute(teller);
|
exec.execute(teller);
|
||||||
workingTellers.add(teller);
|
workingTellers.add(teller);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void adjustTellerNumber() {
|
public void adjustTellerNumber() {
|
||||||
// This is actually a control system. By adjusting
|
// This is actually a control system. By adjusting
|
||||||
// the numbers, you can reveal stability issues in
|
// the numbers, you can reveal stability issues in
|
||||||
// the control mechanism.
|
// the control mechanism.
|
||||||
// If line is too long, add another teller:
|
// If line is too long, add another teller:
|
||||||
if(customers.size() / workingTellers.size() > 2) {
|
if (customers.size() / workingTellers.size() > 2) {
|
||||||
// If tellers are on break or doing
|
// If tellers are on break or doing
|
||||||
// another job, bring one back:
|
// another job, bring one back:
|
||||||
if(tellersDoingOtherThings.size() > 0) {
|
if (tellersDoingOtherThings.size() > 0) {
|
||||||
Teller teller = tellersDoingOtherThings.remove();
|
Teller teller = tellersDoingOtherThings.remove();
|
||||||
teller.serveCustomerLine();
|
teller.serveCustomerLine();
|
||||||
workingTellers.offer(teller);
|
workingTellers.offer(teller);
|
||||||
@@ -135,45 +167,53 @@ class TellerManager implements Runnable {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// If line is short enough, remove a teller:
|
// If line is short enough, remove a teller:
|
||||||
if(workingTellers.size() > 1 &&
|
if (workingTellers.size() > 1 &&
|
||||||
customers.size() / workingTellers.size() < 2) {
|
customers.size() / workingTellers.size() < 2) {
|
||||||
reassignOneTeller();
|
reassignOneTeller();
|
||||||
}
|
}
|
||||||
// If there is no line, we only need one teller:
|
// If there is no line, we only need one teller:
|
||||||
if(customers.size() == 0) {
|
if (customers.size() == 0) {
|
||||||
while(workingTellers.size() > 1) {
|
while (workingTellers.size() > 1) {
|
||||||
reassignOneTeller();
|
reassignOneTeller();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Give a teller a different job or a break:
|
// Give a teller a different job or a break:
|
||||||
private void reassignOneTeller() {
|
private void reassignOneTeller() {
|
||||||
Teller teller = workingTellers.poll();
|
Teller teller = workingTellers.poll();
|
||||||
teller.doSomethingElse();
|
teller.doSomethingElse();
|
||||||
tellersDoingOtherThings.offer(teller);
|
tellersDoingOtherThings.offer(teller);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
while(!Thread.interrupted()) {
|
while (!Thread.interrupted()) {
|
||||||
TimeUnit.MILLISECONDS.sleep(adjustmentPeriod);
|
TimeUnit.MILLISECONDS.sleep(adjustmentPeriod);
|
||||||
adjustTellerNumber();
|
adjustTellerNumber();
|
||||||
System.out.print(customers + " { ");
|
System.out.print(customers + " { ");
|
||||||
for(Teller teller : workingTellers) {
|
for (Teller teller : workingTellers) {
|
||||||
System.out.print(teller.shortString() + " ");
|
System.out.print(teller.shortString() + " ");
|
||||||
}
|
}
|
||||||
System.out.println("}");
|
System.out.println("}");
|
||||||
}
|
}
|
||||||
} catch(InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
System.out.println(this + "interrupted");
|
System.out.println(this + "interrupted");
|
||||||
}
|
}
|
||||||
System.out.println(this + "terminating");
|
System.out.println(this + "terminating");
|
||||||
}
|
}
|
||||||
public String toString() { return "TellerManager "; }
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "TellerManager ";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class BankTellerSimulation {
|
public class BankTellerSimulation {
|
||||||
static final int MAX_LINE_SIZE = 50;
|
static final int MAX_LINE_SIZE = 50;
|
||||||
static final int ADJUSTMENT_PERIOD = 1000;
|
static final int ADJUSTMENT_PERIOD = 1000;
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
ExecutorService exec = Executors.newCachedThreadPool();
|
ExecutorService exec = Executors.newCachedThreadPool();
|
||||||
// If line is too long, customers will leave:
|
// If line is too long, customers will leave:
|
||||||
@@ -183,7 +223,7 @@ public class BankTellerSimulation {
|
|||||||
// Manager will add and remove tellers as necessary:
|
// Manager will add and remove tellers as necessary:
|
||||||
exec.execute(new TellerManager(
|
exec.execute(new TellerManager(
|
||||||
exec, customers, ADJUSTMENT_PERIOD));
|
exec, customers, ADJUSTMENT_PERIOD));
|
||||||
if(args.length > 0) // Optional argument
|
if (args.length > 0) // Optional argument
|
||||||
{
|
{
|
||||||
TimeUnit.SECONDS.sleep(new Integer(args[0]));
|
TimeUnit.SECONDS.sleep(new Integer(args[0]));
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
package concurrency;//: concurrency/CachedThreadPool.java
|
package concurrency;//: concurrency/CachedThreadPool.java
|
||||||
|
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
|
|
||||||
public class CachedThreadPool {
|
public class CachedThreadPool {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
ExecutorService exec = Executors.newCachedThreadPool();
|
ExecutorService exec = Executors.newCachedThreadPool();
|
||||||
for(int i = 0; i < 5; i++) {
|
for (int i = 0; i < 5; i++) {
|
||||||
exec.execute(new LiftOff());
|
exec.execute(new LiftOff());
|
||||||
}
|
}
|
||||||
exec.shutdown();
|
exec.shutdown();
|
||||||
|
|||||||
@@ -1,12 +1,16 @@
|
|||||||
package concurrency;//: concurrency/CallableDemo.java
|
package concurrency;//: concurrency/CallableDemo.java
|
||||||
|
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
class TaskWithResult implements Callable<String> {
|
class TaskWithResult implements Callable<String> {
|
||||||
private int id;
|
private int id;
|
||||||
|
|
||||||
public TaskWithResult(int id) {
|
public TaskWithResult(int id) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String call() {
|
public String call() {
|
||||||
return "result of TaskWithResult " + id;
|
return "result of TaskWithResult " + id;
|
||||||
}
|
}
|
||||||
@@ -17,17 +21,17 @@ public class CallableDemo {
|
|||||||
ExecutorService exec = Executors.newCachedThreadPool();
|
ExecutorService exec = Executors.newCachedThreadPool();
|
||||||
ArrayList<Future<String>> results =
|
ArrayList<Future<String>> results =
|
||||||
new ArrayList<Future<String>>();
|
new ArrayList<Future<String>>();
|
||||||
for(int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
results.add(exec.submit(new TaskWithResult(i)));
|
results.add(exec.submit(new TaskWithResult(i)));
|
||||||
}
|
}
|
||||||
for(Future<String> fs : results) {
|
for (Future<String> fs : results) {
|
||||||
try {
|
try {
|
||||||
// get() blocks until completion:
|
// get() blocks until completion:
|
||||||
System.out.println(fs.get());
|
System.out.println(fs.get());
|
||||||
} catch(InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
System.out.println(e);
|
System.out.println(e);
|
||||||
return;
|
return;
|
||||||
} catch(ExecutionException e) {
|
} catch (ExecutionException e) {
|
||||||
System.out.println(e);
|
System.out.println(e);
|
||||||
} finally {
|
} finally {
|
||||||
exec.shutdown();
|
exec.shutdown();
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
package concurrency;//: concurrency/CaptureUncaughtException.java
|
package concurrency;//: concurrency/CaptureUncaughtException.java
|
||||||
|
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
|
|
||||||
class ExceptionThread2 implements Runnable {
|
class ExceptionThread2 implements Runnable {
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
Thread t = Thread.currentThread();
|
Thread t = Thread.currentThread();
|
||||||
System.out.println("run() by " + t);
|
System.out.println("run() by " + t);
|
||||||
@@ -12,13 +14,15 @@ class ExceptionThread2 implements Runnable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class MyUncaughtExceptionHandler implements
|
class MyUncaughtExceptionHandler implements
|
||||||
Thread.UncaughtExceptionHandler {
|
Thread.UncaughtExceptionHandler {
|
||||||
|
@Override
|
||||||
public void uncaughtException(Thread t, Throwable e) {
|
public void uncaughtException(Thread t, Throwable e) {
|
||||||
System.out.println("caught " + e);
|
System.out.println("caught " + e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class HandlerThreadFactory implements ThreadFactory {
|
class HandlerThreadFactory implements ThreadFactory {
|
||||||
|
@Override
|
||||||
public Thread newThread(Runnable r) {
|
public Thread newThread(Runnable r) {
|
||||||
System.out.println(this + " creating new Thread");
|
System.out.println(this + " creating new Thread");
|
||||||
Thread t = new Thread(r);
|
Thread t = new Thread(r);
|
||||||
|
|||||||
@@ -1,22 +1,42 @@
|
|||||||
package concurrency;//: concurrency/CarBuilder.java
|
package concurrency;//: concurrency/CarBuilder.java
|
||||||
// A complex example of tasks working together.
|
// A complex example of tasks working together.
|
||||||
|
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import static net.mindview.util.Print.*;
|
import static net.mindview.util.Print.*;
|
||||||
|
|
||||||
class Car {
|
class Car {
|
||||||
private final int id;
|
private final int id;
|
||||||
private boolean
|
private boolean
|
||||||
engine = false, driveTrain = false, wheels = false;
|
engine = false, driveTrain = false, wheels = false;
|
||||||
public Car(int idn) { id = idn; }
|
|
||||||
|
public Car(int idn) {
|
||||||
|
id = idn;
|
||||||
|
}
|
||||||
|
|
||||||
// Empty Car object:
|
// Empty Car object:
|
||||||
public Car() { id = -1; }
|
public Car() {
|
||||||
public synchronized int getId() { return id; }
|
id = -1;
|
||||||
public synchronized void addEngine() { engine = true; }
|
}
|
||||||
|
|
||||||
|
public synchronized int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void addEngine() {
|
||||||
|
engine = true;
|
||||||
|
}
|
||||||
|
|
||||||
public synchronized void addDriveTrain() {
|
public synchronized void addDriveTrain() {
|
||||||
driveTrain = true;
|
driveTrain = true;
|
||||||
}
|
}
|
||||||
public synchronized void addWheels() { wheels = true; }
|
|
||||||
|
public synchronized void addWheels() {
|
||||||
|
wheels = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public synchronized String toString() {
|
public synchronized String toString() {
|
||||||
return "Car " + id + " [" + " engine: " + engine
|
return "Car " + id + " [" + " engine: " + engine
|
||||||
+ " driveTrain: " + driveTrain
|
+ " driveTrain: " + driveTrain
|
||||||
@@ -24,15 +44,21 @@ class Car {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class CarQueue extends LinkedBlockingQueue<Car> {}
|
class CarQueue extends LinkedBlockingQueue<Car> {
|
||||||
|
}
|
||||||
|
|
||||||
class ChassisBuilder implements Runnable {
|
class ChassisBuilder implements Runnable {
|
||||||
private CarQueue carQueue;
|
private CarQueue carQueue;
|
||||||
private int counter = 0;
|
private int counter = 0;
|
||||||
public ChassisBuilder(CarQueue cq) { carQueue = cq; }
|
|
||||||
|
public ChassisBuilder(CarQueue cq) {
|
||||||
|
carQueue = cq;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
while(!Thread.interrupted()) {
|
while (!Thread.interrupted()) {
|
||||||
TimeUnit.MILLISECONDS.sleep(500);
|
TimeUnit.MILLISECONDS.sleep(500);
|
||||||
// Make chassis:
|
// Make chassis:
|
||||||
Car c = new Car(counter++);
|
Car c = new Car(counter++);
|
||||||
@@ -40,7 +66,7 @@ class ChassisBuilder implements Runnable {
|
|||||||
// Insert into queue
|
// Insert into queue
|
||||||
carQueue.put(c);
|
carQueue.put(c);
|
||||||
}
|
}
|
||||||
} catch(InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
print("Interrupted: ChassisBuilder");
|
print("Interrupted: ChassisBuilder");
|
||||||
}
|
}
|
||||||
print("ChassisBuilder off");
|
print("ChassisBuilder off");
|
||||||
@@ -52,16 +78,25 @@ class Assembler implements Runnable {
|
|||||||
private Car car;
|
private Car car;
|
||||||
private CyclicBarrier barrier = new CyclicBarrier(4);
|
private CyclicBarrier barrier = new CyclicBarrier(4);
|
||||||
private RobotPool robotPool;
|
private RobotPool robotPool;
|
||||||
public Assembler(CarQueue cq, CarQueue fq, RobotPool rp){
|
|
||||||
|
public Assembler(CarQueue cq, CarQueue fq, RobotPool rp) {
|
||||||
chassisQueue = cq;
|
chassisQueue = cq;
|
||||||
finishingQueue = fq;
|
finishingQueue = fq;
|
||||||
robotPool = rp;
|
robotPool = rp;
|
||||||
}
|
}
|
||||||
public Car car() { return car; }
|
|
||||||
public CyclicBarrier barrier() { return barrier; }
|
public Car car() {
|
||||||
|
return car;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CyclicBarrier barrier() {
|
||||||
|
return barrier;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
while(!Thread.interrupted()) {
|
while (!Thread.interrupted()) {
|
||||||
// Blocks until chassis is available:
|
// Blocks until chassis is available:
|
||||||
car = chassisQueue.take();
|
car = chassisQueue.take();
|
||||||
// Hire robots to perform work:
|
// Hire robots to perform work:
|
||||||
@@ -72,9 +107,9 @@ class Assembler implements Runnable {
|
|||||||
// Put car into finishingQueue for further work
|
// Put car into finishingQueue for further work
|
||||||
finishingQueue.put(car);
|
finishingQueue.put(car);
|
||||||
}
|
}
|
||||||
} catch(InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
print("Exiting Assembler via interrupt");
|
print("Exiting Assembler via interrupt");
|
||||||
} catch(BrokenBarrierException e) {
|
} catch (BrokenBarrierException e) {
|
||||||
// This one we want to know about
|
// This one we want to know about
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
@@ -84,13 +119,18 @@ class Assembler implements Runnable {
|
|||||||
|
|
||||||
class Reporter implements Runnable {
|
class Reporter implements Runnable {
|
||||||
private CarQueue carQueue;
|
private CarQueue carQueue;
|
||||||
public Reporter(CarQueue cq) { carQueue = cq; }
|
|
||||||
|
public Reporter(CarQueue cq) {
|
||||||
|
carQueue = cq;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
while(!Thread.interrupted()) {
|
while (!Thread.interrupted()) {
|
||||||
print(carQueue.take());
|
print(carQueue.take());
|
||||||
}
|
}
|
||||||
} catch(InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
print("Exiting Reporter via interrupt");
|
print("Exiting Reporter via interrupt");
|
||||||
}
|
}
|
||||||
print("Reporter off");
|
print("Reporter off");
|
||||||
@@ -99,52 +139,71 @@ class Reporter implements Runnable {
|
|||||||
|
|
||||||
abstract class Robot implements Runnable {
|
abstract class Robot implements Runnable {
|
||||||
private RobotPool pool;
|
private RobotPool pool;
|
||||||
public Robot(RobotPool p) { pool = p; }
|
|
||||||
|
public Robot(RobotPool p) {
|
||||||
|
pool = p;
|
||||||
|
}
|
||||||
|
|
||||||
protected Assembler assembler;
|
protected Assembler assembler;
|
||||||
|
|
||||||
public Robot assignAssembler(Assembler assembler) {
|
public Robot assignAssembler(Assembler assembler) {
|
||||||
this.assembler = assembler;
|
this.assembler = assembler;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean engage = false;
|
private boolean engage = false;
|
||||||
|
|
||||||
public synchronized void engage() {
|
public synchronized void engage() {
|
||||||
engage = true;
|
engage = true;
|
||||||
notifyAll();
|
notifyAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
// The part of run() that's different for each robot:
|
// The part of run() that's different for each robot:
|
||||||
abstract protected void performService();
|
abstract protected void performService();
|
||||||
|
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
powerDown(); // Wait until needed
|
powerDown(); // Wait until needed
|
||||||
while(!Thread.interrupted()) {
|
while (!Thread.interrupted()) {
|
||||||
performService();
|
performService();
|
||||||
assembler.barrier().await(); // Synchronize
|
assembler.barrier().await(); // Synchronize
|
||||||
// We're done with that job...
|
// We're done with that job...
|
||||||
powerDown();
|
powerDown();
|
||||||
}
|
}
|
||||||
} catch(InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
print("Exiting " + this + " via interrupt");
|
print("Exiting " + this + " via interrupt");
|
||||||
} catch(BrokenBarrierException e) {
|
} catch (BrokenBarrierException e) {
|
||||||
// This one we want to know about
|
// This one we want to know about
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
print(this + " off");
|
print(this + " off");
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void
|
private synchronized void
|
||||||
powerDown() throws InterruptedException {
|
powerDown() throws InterruptedException {
|
||||||
engage = false;
|
engage = false;
|
||||||
assembler = null; // Disconnect from the Assembler
|
assembler = null; // Disconnect from the Assembler
|
||||||
// Put ourselves back in the available pool:
|
// Put ourselves back in the available pool:
|
||||||
pool.release(this);
|
pool.release(this);
|
||||||
while(engage == false) // Power down
|
while (engage == false) // Power down
|
||||||
{
|
{
|
||||||
wait();
|
wait();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public String toString() { return getClass().getName(); }
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return getClass().getName();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class EngineRobot extends Robot {
|
class EngineRobot extends Robot {
|
||||||
public EngineRobot(RobotPool pool) { super(pool); }
|
public EngineRobot(RobotPool pool) {
|
||||||
|
super(pool);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
protected void performService() {
|
protected void performService() {
|
||||||
print(this + " installing engine");
|
print(this + " installing engine");
|
||||||
assembler.car().addEngine();
|
assembler.car().addEngine();
|
||||||
@@ -152,7 +211,11 @@ class EngineRobot extends Robot {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class DriveTrainRobot extends Robot {
|
class DriveTrainRobot extends Robot {
|
||||||
public DriveTrainRobot(RobotPool pool) { super(pool); }
|
public DriveTrainRobot(RobotPool pool) {
|
||||||
|
super(pool);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
protected void performService() {
|
protected void performService() {
|
||||||
print(this + " installing DriveTrain");
|
print(this + " installing DriveTrain");
|
||||||
assembler.car().addDriveTrain();
|
assembler.car().addDriveTrain();
|
||||||
@@ -160,7 +223,11 @@ class DriveTrainRobot extends Robot {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class WheelRobot extends Robot {
|
class WheelRobot extends Robot {
|
||||||
public WheelRobot(RobotPool pool) { super(pool); }
|
public WheelRobot(RobotPool pool) {
|
||||||
|
super(pool);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
protected void performService() {
|
protected void performService() {
|
||||||
print(this + " installing Wheels");
|
print(this + " installing Wheels");
|
||||||
assembler.car().addWheels();
|
assembler.car().addWheels();
|
||||||
@@ -170,15 +237,17 @@ class WheelRobot extends Robot {
|
|||||||
class RobotPool {
|
class RobotPool {
|
||||||
// Quietly prevents identical entries:
|
// Quietly prevents identical entries:
|
||||||
private Set<Robot> pool = new HashSet<Robot>();
|
private Set<Robot> pool = new HashSet<Robot>();
|
||||||
|
|
||||||
public synchronized void add(Robot r) {
|
public synchronized void add(Robot r) {
|
||||||
pool.add(r);
|
pool.add(r);
|
||||||
notifyAll();
|
notifyAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void
|
public synchronized void
|
||||||
hire(Class<? extends Robot> robotType, Assembler d)
|
hire(Class<? extends Robot> robotType, Assembler d)
|
||||||
throws InterruptedException {
|
throws InterruptedException {
|
||||||
for(Robot r : pool) {
|
for (Robot r : pool) {
|
||||||
if(r.getClass().equals(robotType)) {
|
if (r.getClass().equals(robotType)) {
|
||||||
pool.remove(r);
|
pool.remove(r);
|
||||||
r.assignAssembler(d);
|
r.assignAssembler(d);
|
||||||
r.engage(); // Power it up to do the task
|
r.engage(); // Power it up to do the task
|
||||||
@@ -188,7 +257,10 @@ class RobotPool {
|
|||||||
wait(); // None available
|
wait(); // None available
|
||||||
hire(robotType, d); // Try again, recursively
|
hire(robotType, d); // Try again, recursively
|
||||||
}
|
}
|
||||||
public synchronized void release(Robot r) { add(r); }
|
|
||||||
|
public synchronized void release(Robot r) {
|
||||||
|
add(r);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class CarBuilder {
|
public class CarBuilder {
|
||||||
|
|||||||
@@ -3,13 +3,14 @@ package concurrency;//: concurrency/Chopstick.java
|
|||||||
|
|
||||||
public class Chopstick {
|
public class Chopstick {
|
||||||
private boolean taken = false;
|
private boolean taken = false;
|
||||||
public synchronized
|
|
||||||
void take() throws InterruptedException {
|
public synchronized void take() throws InterruptedException {
|
||||||
while(taken) {
|
while (taken) {
|
||||||
wait();
|
wait();
|
||||||
}
|
}
|
||||||
taken = true;
|
taken = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void drop() {
|
public synchronized void drop() {
|
||||||
taken = false;
|
taken = false;
|
||||||
notifyAll();
|
notifyAll();
|
||||||
|
|||||||
@@ -2,9 +2,11 @@ package concurrency;//: concurrency/CloseResource.java
|
|||||||
// Interrupting a blocked task by
|
// Interrupting a blocked task by
|
||||||
// closing the underlying resource.
|
// closing the underlying resource.
|
||||||
// {RunByHand}
|
// {RunByHand}
|
||||||
|
|
||||||
import java.net.*;
|
import java.net.*;
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
|
||||||
import static net.mindview.util.Print.*;
|
import static net.mindview.util.Print.*;
|
||||||
|
|
||||||
public class CloseResource {
|
public class CloseResource {
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package concurrency;//: concurrency/CountDownLatchDemo.java
|
package concurrency;//: concurrency/CountDownLatchDemo.java
|
||||||
|
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import static net.mindview.util.Print.*;
|
import static net.mindview.util.Print.*;
|
||||||
|
|
||||||
// Performs some portion of a task:
|
// Performs some portion of a task:
|
||||||
@@ -9,21 +11,27 @@ class TaskPortion implements Runnable {
|
|||||||
private final int id = counter++;
|
private final int id = counter++;
|
||||||
private static Random rand = new Random(47);
|
private static Random rand = new Random(47);
|
||||||
private final CountDownLatch latch;
|
private final CountDownLatch latch;
|
||||||
|
|
||||||
TaskPortion(CountDownLatch latch) {
|
TaskPortion(CountDownLatch latch) {
|
||||||
this.latch = latch;
|
this.latch = latch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
doWork();
|
doWork();
|
||||||
latch.countDown();
|
latch.countDown();
|
||||||
} catch(InterruptedException ex) {
|
} catch (InterruptedException ex) {
|
||||||
// Acceptable way to exit
|
// Acceptable way to exit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void doWork() throws InterruptedException {
|
public void doWork() throws InterruptedException {
|
||||||
TimeUnit.MILLISECONDS.sleep(rand.nextInt(2000));
|
TimeUnit.MILLISECONDS.sleep(rand.nextInt(2000));
|
||||||
print(this + "completed");
|
print(this + "completed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return String.format("%1$-3d ", id);
|
return String.format("%1$-3d ", id);
|
||||||
}
|
}
|
||||||
@@ -34,17 +42,22 @@ class WaitingTask implements Runnable {
|
|||||||
private static int counter = 0;
|
private static int counter = 0;
|
||||||
private final int id = counter++;
|
private final int id = counter++;
|
||||||
private final CountDownLatch latch;
|
private final CountDownLatch latch;
|
||||||
|
|
||||||
WaitingTask(CountDownLatch latch) {
|
WaitingTask(CountDownLatch latch) {
|
||||||
this.latch = latch;
|
this.latch = latch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
latch.await();
|
latch.await();
|
||||||
print("Latch barrier passed for " + this);
|
print("Latch barrier passed for " + this);
|
||||||
} catch(InterruptedException ex) {
|
} catch (InterruptedException ex) {
|
||||||
print(this + " interrupted");
|
print(this + " interrupted");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return String.format("WaitingTask %1$-3d ", id);
|
return String.format("WaitingTask %1$-3d ", id);
|
||||||
}
|
}
|
||||||
@@ -52,14 +65,15 @@ class WaitingTask implements Runnable {
|
|||||||
|
|
||||||
public class CountDownLatchDemo {
|
public class CountDownLatchDemo {
|
||||||
static final int SIZE = 100;
|
static final int SIZE = 100;
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
ExecutorService exec = Executors.newCachedThreadPool();
|
ExecutorService exec = Executors.newCachedThreadPool();
|
||||||
// All must share a single CountDownLatch object:
|
// All must share a single CountDownLatch object:
|
||||||
CountDownLatch latch = new CountDownLatch(SIZE);
|
CountDownLatch latch = new CountDownLatch(SIZE);
|
||||||
for(int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
exec.execute(new WaitingTask(latch));
|
exec.execute(new WaitingTask(latch));
|
||||||
}
|
}
|
||||||
for(int i = 0; i < SIZE; i++) {
|
for (int i = 0; i < SIZE; i++) {
|
||||||
exec.execute(new TaskPortion(latch));
|
exec.execute(new TaskPortion(latch));
|
||||||
}
|
}
|
||||||
print("Launched all tasks");
|
print("Launched all tasks");
|
||||||
|
|||||||
@@ -3,33 +3,54 @@
|
|||||||
// demonstrates protection of a non-thread-safe class
|
// demonstrates protection of a non-thread-safe class
|
||||||
// with a thread-safe one.
|
// with a thread-safe one.
|
||||||
package concurrency;
|
package concurrency;
|
||||||
|
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
import java.util.concurrent.atomic.*;
|
import java.util.concurrent.atomic.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
class Pair { // Not thread-safe
|
class Pair { // Not thread-safe
|
||||||
private int x, y;
|
private int x, y;
|
||||||
|
|
||||||
public Pair(int x, int y) {
|
public Pair(int x, int y) {
|
||||||
this.x = x;
|
this.x = x;
|
||||||
this.y = y;
|
this.y = y;
|
||||||
}
|
}
|
||||||
public Pair() { this(0, 0); }
|
|
||||||
public int getX() { return x; }
|
public Pair() {
|
||||||
public int getY() { return y; }
|
this(0, 0);
|
||||||
public void incrementX() { x++; }
|
}
|
||||||
public void incrementY() { y++; }
|
|
||||||
|
public int getX() {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getY() {
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void incrementX() {
|
||||||
|
x++;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void incrementY() {
|
||||||
|
y++;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "x: " + x + ", y: " + y;
|
return "x: " + x + ", y: " + y;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class PairValuesNotEqualException
|
public class PairValuesNotEqualException
|
||||||
extends RuntimeException {
|
extends RuntimeException {
|
||||||
public PairValuesNotEqualException() {
|
public PairValuesNotEqualException() {
|
||||||
super("Pair values not equal: " + Pair.this);
|
super("Pair values not equal: " + Pair.this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Arbitrary invariant -- both variables must be equal:
|
// Arbitrary invariant -- both variables must be equal:
|
||||||
public void checkState() {
|
public void checkState() {
|
||||||
if(x != y) {
|
if (x != y) {
|
||||||
throw new PairValuesNotEqualException();
|
throw new PairValuesNotEqualException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -41,22 +62,27 @@ abstract class PairManager {
|
|||||||
protected Pair p = new Pair();
|
protected Pair p = new Pair();
|
||||||
private List<Pair> storage =
|
private List<Pair> storage =
|
||||||
Collections.synchronizedList(new ArrayList<Pair>());
|
Collections.synchronizedList(new ArrayList<Pair>());
|
||||||
|
|
||||||
public synchronized Pair getPair() {
|
public synchronized Pair getPair() {
|
||||||
// Make a copy to keep the original safe:
|
// Make a copy to keep the original safe:
|
||||||
return new Pair(p.getX(), p.getY());
|
return new Pair(p.getX(), p.getY());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assume this is a time consuming operation
|
// Assume this is a time consuming operation
|
||||||
protected void store(Pair p) {
|
protected void store(Pair p) {
|
||||||
storage.add(p);
|
storage.add(p);
|
||||||
try {
|
try {
|
||||||
TimeUnit.MILLISECONDS.sleep(50);
|
TimeUnit.MILLISECONDS.sleep(50);
|
||||||
} catch(InterruptedException ignore) {}
|
} catch (InterruptedException ignore) {
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public abstract void increment();
|
public abstract void increment();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Synchronize the entire method:
|
// Synchronize the entire method:
|
||||||
class PairManager1 extends PairManager {
|
class PairManager1 extends PairManager {
|
||||||
|
@Override
|
||||||
public synchronized void increment() {
|
public synchronized void increment() {
|
||||||
p.incrementX();
|
p.incrementX();
|
||||||
p.incrementY();
|
p.incrementY();
|
||||||
@@ -66,9 +92,10 @@ class PairManager1 extends PairManager {
|
|||||||
|
|
||||||
// Use a critical section:
|
// Use a critical section:
|
||||||
class PairManager2 extends PairManager {
|
class PairManager2 extends PairManager {
|
||||||
|
@Override
|
||||||
public void increment() {
|
public void increment() {
|
||||||
Pair temp;
|
Pair temp;
|
||||||
synchronized(this) {
|
synchronized (this) {
|
||||||
p.incrementX();
|
p.incrementX();
|
||||||
p.incrementY();
|
p.incrementY();
|
||||||
temp = getPair();
|
temp = getPair();
|
||||||
@@ -79,14 +106,19 @@ class PairManager2 extends PairManager {
|
|||||||
|
|
||||||
class PairManipulator implements Runnable {
|
class PairManipulator implements Runnable {
|
||||||
private PairManager pm;
|
private PairManager pm;
|
||||||
|
|
||||||
public PairManipulator(PairManager pm) {
|
public PairManipulator(PairManager pm) {
|
||||||
this.pm = pm;
|
this.pm = pm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
while(true) {
|
while (true) {
|
||||||
pm.increment();
|
pm.increment();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Pair: " + pm.getPair() +
|
return "Pair: " + pm.getPair() +
|
||||||
" checkCounter = " + pm.checkCounter.get();
|
" checkCounter = " + pm.checkCounter.get();
|
||||||
@@ -95,11 +127,14 @@ class PairManipulator implements Runnable {
|
|||||||
|
|
||||||
class PairChecker implements Runnable {
|
class PairChecker implements Runnable {
|
||||||
private PairManager pm;
|
private PairManager pm;
|
||||||
|
|
||||||
public PairChecker(PairManager pm) {
|
public PairChecker(PairManager pm) {
|
||||||
this.pm = pm;
|
this.pm = pm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
while(true) {
|
while (true) {
|
||||||
pm.checkCounter.incrementAndGet();
|
pm.checkCounter.incrementAndGet();
|
||||||
pm.getPair().checkState();
|
pm.getPair().checkState();
|
||||||
}
|
}
|
||||||
@@ -123,12 +158,13 @@ public class CriticalSection {
|
|||||||
exec.execute(pcheck2);
|
exec.execute(pcheck2);
|
||||||
try {
|
try {
|
||||||
TimeUnit.MILLISECONDS.sleep(500);
|
TimeUnit.MILLISECONDS.sleep(500);
|
||||||
} catch(InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
System.out.println("Sleep interrupted");
|
System.out.println("Sleep interrupted");
|
||||||
}
|
}
|
||||||
System.out.println("pm1: " + pm1 + "\npm2: " + pm2);
|
System.out.println("pm1: " + pm1 + "\npm2: " + pm2);
|
||||||
System.exit(0);
|
System.exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
PairManager
|
PairManager
|
||||||
pman1 = new PairManager1(),
|
pman1 = new PairManager1(),
|
||||||
|
|||||||
@@ -1,24 +1,29 @@
|
|||||||
package concurrency;//: concurrency/DaemonFromFactory.java
|
package concurrency;//: concurrency/DaemonFromFactory.java
|
||||||
// Using a Thread Factory to create daemons.
|
// Using a Thread Factory to create daemons.
|
||||||
|
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
|
|
||||||
import net.mindview.util.*;
|
import net.mindview.util.*;
|
||||||
|
|
||||||
import static net.mindview.util.Print.*;
|
import static net.mindview.util.Print.*;
|
||||||
|
|
||||||
public class DaemonFromFactory implements Runnable {
|
public class DaemonFromFactory implements Runnable {
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
while(true) {
|
while (true) {
|
||||||
TimeUnit.MILLISECONDS.sleep(100);
|
TimeUnit.MILLISECONDS.sleep(100);
|
||||||
print(Thread.currentThread() + " " + this);
|
print(Thread.currentThread() + " " + this);
|
||||||
}
|
}
|
||||||
} catch(InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
print("Interrupted");
|
print("Interrupted");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
ExecutorService exec = Executors.newCachedThreadPool(
|
ExecutorService exec = Executors.newCachedThreadPool(
|
||||||
new DaemonThreadFactory());
|
new DaemonThreadFactory());
|
||||||
for(int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
exec.execute(new DaemonFromFactory());
|
exec.execute(new DaemonFromFactory());
|
||||||
}
|
}
|
||||||
print("All daemons started");
|
print("All daemons started");
|
||||||
|
|||||||
@@ -1,29 +1,34 @@
|
|||||||
package concurrency;//: concurrency/Daemons.java
|
package concurrency;//: concurrency/Daemons.java
|
||||||
// Daemon threads spawn other daemon threads.
|
// Daemon threads spawn other daemon threads.
|
||||||
|
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
|
|
||||||
import static net.mindview.util.Print.*;
|
import static net.mindview.util.Print.*;
|
||||||
|
|
||||||
class Daemon implements Runnable {
|
class Daemon implements Runnable {
|
||||||
private Thread[] t = new Thread[10];
|
private Thread[] t = new Thread[10];
|
||||||
|
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
for(int i = 0; i < t.length; i++) {
|
for (int i = 0; i < t.length; i++) {
|
||||||
t[i] = new Thread(new DaemonSpawn());
|
t[i] = new Thread(new DaemonSpawn());
|
||||||
t[i].start();
|
t[i].start();
|
||||||
printnb("DaemonSpawn " + i + " started, ");
|
printnb("DaemonSpawn " + i + " started, ");
|
||||||
}
|
}
|
||||||
for(int i = 0; i < t.length; i++) {
|
for (int i = 0; i < t.length; i++) {
|
||||||
printnb("t[" + i + "].isDaemon() = " +
|
printnb("t[" + i + "].isDaemon() = " +
|
||||||
t[i].isDaemon() + ", ");
|
t[i].isDaemon() + ", ");
|
||||||
}
|
}
|
||||||
while(true) {
|
while (true) {
|
||||||
Thread.yield();
|
Thread.yield();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class DaemonSpawn implements Runnable {
|
class DaemonSpawn implements Runnable {
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
while(true) {
|
while (true) {
|
||||||
Thread.yield();
|
Thread.yield();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,17 @@
|
|||||||
package concurrency;//: concurrency/DaemonsDontRunFinally.java
|
package concurrency;//: concurrency/DaemonsDontRunFinally.java
|
||||||
// Daemon threads don't run the finally clause
|
// Daemon threads don't run the finally clause
|
||||||
|
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
|
|
||||||
import static net.mindview.util.Print.*;
|
import static net.mindview.util.Print.*;
|
||||||
|
|
||||||
class ADaemon implements Runnable {
|
class ADaemon implements Runnable {
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
print("Starting ADaemon");
|
print("Starting ADaemon");
|
||||||
TimeUnit.SECONDS.sleep(1);
|
TimeUnit.SECONDS.sleep(1);
|
||||||
} catch(InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
print("Exiting via InterruptedException");
|
print("Exiting via InterruptedException");
|
||||||
} finally {
|
} finally {
|
||||||
print("This should always run?");
|
print("This should always run?");
|
||||||
|
|||||||
@@ -1,28 +1,29 @@
|
|||||||
package concurrency;//: concurrency/DeadlockingDiningPhilosophers.java
|
package concurrency;//: concurrency/DeadlockingDiningPhilosophers.java
|
||||||
// Demonstrates how deadlock can be hidden in a program.
|
// Demonstrates how deadlock can be hidden in a program.
|
||||||
// {Args: 0 5 timeout}
|
// {Args: 0 5 timeout}
|
||||||
|
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
|
|
||||||
public class DeadlockingDiningPhilosophers {
|
public class DeadlockingDiningPhilosophers {
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
int ponder = 5;
|
int ponder = 5;
|
||||||
if(args.length > 0) {
|
if (args.length > 0) {
|
||||||
ponder = Integer.parseInt(args[0]);
|
ponder = Integer.parseInt(args[0]);
|
||||||
}
|
}
|
||||||
int size = 5;
|
int size = 5;
|
||||||
if(args.length > 1) {
|
if (args.length > 1) {
|
||||||
size = Integer.parseInt(args[1]);
|
size = Integer.parseInt(args[1]);
|
||||||
}
|
}
|
||||||
ExecutorService exec = Executors.newCachedThreadPool();
|
ExecutorService exec = Executors.newCachedThreadPool();
|
||||||
Chopstick[] sticks = new Chopstick[size];
|
Chopstick[] sticks = new Chopstick[size];
|
||||||
for(int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
sticks[i] = new Chopstick();
|
sticks[i] = new Chopstick();
|
||||||
}
|
}
|
||||||
for(int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
exec.execute(new Philosopher(
|
exec.execute(new Philosopher(
|
||||||
sticks[i], sticks[(i+1) % size], i, ponder));
|
sticks[i], sticks[(i + 1) % size], i, ponder));
|
||||||
}
|
}
|
||||||
if(args.length == 3 && args[2].equals("timeout")) {
|
if (args.length == 3 && args[2].equals("timeout")) {
|
||||||
TimeUnit.SECONDS.sleep(5);
|
TimeUnit.SECONDS.sleep(5);
|
||||||
} else {
|
} else {
|
||||||
System.out.println("Press 'Enter' to quit");
|
System.out.println("Press 'Enter' to quit");
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package concurrency;//: concurrency/DelayQueueDemo.java
|
package concurrency;//: concurrency/DelayQueueDemo.java
|
||||||
|
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import static java.util.concurrent.TimeUnit.*;
|
import static java.util.concurrent.TimeUnit.*;
|
||||||
import static net.mindview.util.Print.*;
|
import static net.mindview.util.Print.*;
|
||||||
|
|
||||||
@@ -11,42 +13,58 @@ class DelayedTask implements Runnable, Delayed {
|
|||||||
private final long trigger;
|
private final long trigger;
|
||||||
protected static List<DelayedTask> sequence =
|
protected static List<DelayedTask> sequence =
|
||||||
new ArrayList<DelayedTask>();
|
new ArrayList<DelayedTask>();
|
||||||
|
|
||||||
public DelayedTask(int delayInMilliseconds) {
|
public DelayedTask(int delayInMilliseconds) {
|
||||||
delta = delayInMilliseconds;
|
delta = delayInMilliseconds;
|
||||||
trigger = System.nanoTime() +
|
trigger = System.nanoTime() +
|
||||||
NANOSECONDS.convert(delta, MILLISECONDS);
|
NANOSECONDS.convert(delta, MILLISECONDS);
|
||||||
sequence.add(this);
|
sequence.add(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public long getDelay(TimeUnit unit) {
|
public long getDelay(TimeUnit unit) {
|
||||||
return unit.convert(
|
return unit.convert(
|
||||||
trigger - System.nanoTime(), NANOSECONDS);
|
trigger - System.nanoTime(), NANOSECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int compareTo(Delayed arg) {
|
public int compareTo(Delayed arg) {
|
||||||
DelayedTask that = (DelayedTask)arg;
|
DelayedTask that = (DelayedTask) arg;
|
||||||
if(trigger < that.trigger) {
|
if (trigger < that.trigger) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if(trigger > that.trigger) {
|
if (trigger > that.trigger) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
public void run() { printnb(this + " "); }
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
printnb(this + " ");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return String.format("[%1$-4d]", delta) +
|
return String.format("[%1$-4d]", delta) +
|
||||||
" Task " + id;
|
" Task " + id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String summary() {
|
public String summary() {
|
||||||
return "(" + id + ":" + delta + ")";
|
return "(" + id + ":" + delta + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class EndSentinel extends DelayedTask {
|
public static class EndSentinel extends DelayedTask {
|
||||||
private ExecutorService exec;
|
private ExecutorService exec;
|
||||||
|
|
||||||
public EndSentinel(int delay, ExecutorService e) {
|
public EndSentinel(int delay, ExecutorService e) {
|
||||||
super(delay);
|
super(delay);
|
||||||
exec = e;
|
exec = e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
for(DelayedTask pt : sequence) {
|
for (DelayedTask pt : sequence) {
|
||||||
printnb(pt.summary() + " ");
|
printnb(pt.summary() + " ");
|
||||||
}
|
}
|
||||||
print();
|
print();
|
||||||
@@ -58,15 +76,18 @@ class DelayedTask implements Runnable, Delayed {
|
|||||||
|
|
||||||
class DelayedTaskConsumer implements Runnable {
|
class DelayedTaskConsumer implements Runnable {
|
||||||
private DelayQueue<DelayedTask> q;
|
private DelayQueue<DelayedTask> q;
|
||||||
|
|
||||||
public DelayedTaskConsumer(DelayQueue<DelayedTask> q) {
|
public DelayedTaskConsumer(DelayQueue<DelayedTask> q) {
|
||||||
this.q = q;
|
this.q = q;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
while(!Thread.interrupted()) {
|
while (!Thread.interrupted()) {
|
||||||
q.take().run(); // Run task with the current thread
|
q.take().run(); // Run task with the current thread
|
||||||
}
|
}
|
||||||
} catch(InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
// Acceptable way to exit
|
// Acceptable way to exit
|
||||||
}
|
}
|
||||||
print("Finished DelayedTaskConsumer");
|
print("Finished DelayedTaskConsumer");
|
||||||
@@ -80,7 +101,7 @@ public class DelayQueueDemo {
|
|||||||
DelayQueue<DelayedTask> queue =
|
DelayQueue<DelayedTask> queue =
|
||||||
new DelayQueue<DelayedTask>();
|
new DelayQueue<DelayedTask>();
|
||||||
// Fill with tasks that have random delays:
|
// Fill with tasks that have random delays:
|
||||||
for(int i = 0; i < 20; i++) {
|
for (int i = 0; i < 20; i++) {
|
||||||
queue.put(new DelayedTask(rand.nextInt(5000)));
|
queue.put(new DelayedTask(rand.nextInt(5000)));
|
||||||
}
|
}
|
||||||
// Set the stopping point
|
// Set the stopping point
|
||||||
|
|||||||
@@ -1,31 +1,37 @@
|
|||||||
package concurrency;//: concurrency/EvenChecker.java
|
package concurrency;//: concurrency/EvenChecker.java
|
||||||
|
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
|
|
||||||
public class EvenChecker implements Runnable {
|
public class EvenChecker implements Runnable {
|
||||||
private IntGenerator generator;
|
private IntGenerator generator;
|
||||||
private final int id;
|
private final int id;
|
||||||
|
|
||||||
public EvenChecker(IntGenerator g, int ident) {
|
public EvenChecker(IntGenerator g, int ident) {
|
||||||
generator = g;
|
generator = g;
|
||||||
id = ident;
|
id = ident;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
while(!generator.isCanceled()) {
|
while (!generator.isCanceled()) {
|
||||||
int val = generator.next();
|
int val = generator.next();
|
||||||
if(val % 2 != 0) {
|
if (val % 2 != 0) {
|
||||||
System.out.println(val + " not even!");
|
System.out.println(val + " not even!");
|
||||||
generator.cancel(); // Cancels all EvenCheckers
|
generator.cancel(); // Cancels all EvenCheckers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test any type of IntGenerator:
|
// Test any type of IntGenerator:
|
||||||
public static void test(IntGenerator gp, int count) {
|
public static void test(IntGenerator gp, int count) {
|
||||||
System.out.println("Press Control-C to exit");
|
System.out.println("Press Control-C to exit");
|
||||||
ExecutorService exec = Executors.newCachedThreadPool();
|
ExecutorService exec = Executors.newCachedThreadPool();
|
||||||
for(int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
exec.execute(new EvenChecker(gp, i));
|
exec.execute(new EvenChecker(gp, i));
|
||||||
}
|
}
|
||||||
exec.shutdown();
|
exec.shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default value for count:
|
// Default value for count:
|
||||||
public static void test(IntGenerator gp) {
|
public static void test(IntGenerator gp) {
|
||||||
test(gp, 10);
|
test(gp, 10);
|
||||||
|
|||||||
@@ -3,11 +3,14 @@ package concurrency;//: concurrency/EvenGenerator.java
|
|||||||
|
|
||||||
public class EvenGenerator extends IntGenerator {
|
public class EvenGenerator extends IntGenerator {
|
||||||
private int currentEvenValue = 0;
|
private int currentEvenValue = 0;
|
||||||
|
|
||||||
|
@Override
|
||||||
public int next() {
|
public int next() {
|
||||||
++currentEvenValue; // Danger point here!
|
++currentEvenValue; // Danger point here!
|
||||||
++currentEvenValue;
|
++currentEvenValue;
|
||||||
return currentEvenValue;
|
return currentEvenValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
EvenChecker.test(new EvenGenerator());
|
EvenChecker.test(new EvenGenerator());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
package concurrency;//: concurrency/ExceptionThread.java
|
package concurrency;//: concurrency/ExceptionThread.java
|
||||||
// {ThrowsException}
|
// {ThrowsException}
|
||||||
|
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
|
|
||||||
public class ExceptionThread implements Runnable {
|
public class ExceptionThread implements Runnable {
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
throw new RuntimeException();
|
throw new RuntimeException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
ExecutorService exec = Executors.newCachedThreadPool();
|
ExecutorService exec = Executors.newCachedThreadPool();
|
||||||
exec.execute(new ExceptionThread());
|
exec.execute(new ExceptionThread());
|
||||||
|
|||||||
@@ -1,28 +1,33 @@
|
|||||||
package concurrency;//: concurrency/ExchangerDemo.java
|
package concurrency;//: concurrency/ExchangerDemo.java
|
||||||
|
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import net.mindview.util.*;
|
import net.mindview.util.*;
|
||||||
|
|
||||||
class ExchangerProducer<T> implements Runnable {
|
class ExchangerProducer<T> implements Runnable {
|
||||||
private Generator<T> generator;
|
private Generator<T> generator;
|
||||||
private Exchanger<List<T>> exchanger;
|
private Exchanger<List<T>> exchanger;
|
||||||
private List<T> holder;
|
private List<T> holder;
|
||||||
|
|
||||||
ExchangerProducer(Exchanger<List<T>> exchg,
|
ExchangerProducer(Exchanger<List<T>> exchg,
|
||||||
Generator<T> gen, List<T> holder) {
|
Generator<T> gen, List<T> holder) {
|
||||||
exchanger = exchg;
|
exchanger = exchg;
|
||||||
generator = gen;
|
generator = gen;
|
||||||
this.holder = holder;
|
this.holder = holder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
while(!Thread.interrupted()) {
|
while (!Thread.interrupted()) {
|
||||||
for(int i = 0; i < ExchangerDemo.size; i++) {
|
for (int i = 0; i < ExchangerDemo.size; i++) {
|
||||||
holder.add(generator.next());
|
holder.add(generator.next());
|
||||||
}
|
}
|
||||||
// Exchange full for empty:
|
// Exchange full for empty:
|
||||||
holder = exchanger.exchange(holder);
|
holder = exchanger.exchange(holder);
|
||||||
}
|
}
|
||||||
} catch(InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
// OK to terminate this way.
|
// OK to terminate this way.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -32,20 +37,23 @@ class ExchangerConsumer<T> implements Runnable {
|
|||||||
private Exchanger<List<T>> exchanger;
|
private Exchanger<List<T>> exchanger;
|
||||||
private List<T> holder;
|
private List<T> holder;
|
||||||
private volatile T value;
|
private volatile T value;
|
||||||
ExchangerConsumer(Exchanger<List<T>> ex, List<T> holder){
|
|
||||||
|
ExchangerConsumer(Exchanger<List<T>> ex, List<T> holder) {
|
||||||
exchanger = ex;
|
exchanger = ex;
|
||||||
this.holder = holder;
|
this.holder = holder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
while(!Thread.interrupted()) {
|
while (!Thread.interrupted()) {
|
||||||
holder = exchanger.exchange(holder);
|
holder = exchanger.exchange(holder);
|
||||||
for(T x : holder) {
|
for (T x : holder) {
|
||||||
value = x; // Fetch out value
|
value = x; // Fetch out value
|
||||||
holder.remove(x); // OK for CopyOnWriteArrayList
|
holder.remove(x); // OK for CopyOnWriteArrayList
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch(InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
// OK to terminate this way.
|
// OK to terminate this way.
|
||||||
}
|
}
|
||||||
System.out.println("Final value: " + value);
|
System.out.println("Final value: " + value);
|
||||||
@@ -55,11 +63,12 @@ class ExchangerConsumer<T> implements Runnable {
|
|||||||
public class ExchangerDemo {
|
public class ExchangerDemo {
|
||||||
static int size = 10;
|
static int size = 10;
|
||||||
static int delay = 5; // Seconds
|
static int delay = 5; // Seconds
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
if(args.length > 0) {
|
if (args.length > 0) {
|
||||||
size = new Integer(args[0]);
|
size = new Integer(args[0]);
|
||||||
}
|
}
|
||||||
if(args.length > 1) {
|
if (args.length > 1) {
|
||||||
delay = new Integer(args[1]);
|
delay = new Integer(args[1]);
|
||||||
}
|
}
|
||||||
ExecutorService exec = Executors.newCachedThreadPool();
|
ExecutorService exec = Executors.newCachedThreadPool();
|
||||||
@@ -70,7 +79,7 @@ public class ExchangerDemo {
|
|||||||
exec.execute(new ExchangerProducer<Fat>(xc,
|
exec.execute(new ExchangerProducer<Fat>(xc,
|
||||||
BasicGenerator.create(Fat.class), producerList));
|
BasicGenerator.create(Fat.class), producerList));
|
||||||
exec.execute(
|
exec.execute(
|
||||||
new ExchangerConsumer<Fat>(xc,consumerList));
|
new ExchangerConsumer<Fat>(xc, consumerList));
|
||||||
TimeUnit.SECONDS.sleep(delay);
|
TimeUnit.SECONDS.sleep(delay);
|
||||||
exec.shutdownNow();
|
exec.shutdownNow();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
//: concurrency/ExplicitCriticalSection.java
|
//: concurrency/ExplicitCriticalSection.java
|
||||||
// Using explicit Lock objects to create critical sections.
|
// Using explicit Lock objects to create critical sections.
|
||||||
package concurrency;
|
package concurrency;
|
||||||
|
|
||||||
import java.util.concurrent.locks.*;
|
import java.util.concurrent.locks.*;
|
||||||
|
|
||||||
// Synchronize the entire method:
|
// Synchronize the entire method:
|
||||||
class ExplicitPairManager1 extends PairManager {
|
class ExplicitPairManager1 extends PairManager {
|
||||||
private Lock lock = new ReentrantLock();
|
private Lock lock = new ReentrantLock();
|
||||||
|
|
||||||
|
@Override
|
||||||
public synchronized void increment() {
|
public synchronized void increment() {
|
||||||
lock.lock();
|
lock.lock();
|
||||||
try {
|
try {
|
||||||
@@ -21,6 +24,8 @@ class ExplicitPairManager1 extends PairManager {
|
|||||||
// Use a critical section:
|
// Use a critical section:
|
||||||
class ExplicitPairManager2 extends PairManager {
|
class ExplicitPairManager2 extends PairManager {
|
||||||
private Lock lock = new ReentrantLock();
|
private Lock lock = new ReentrantLock();
|
||||||
|
|
||||||
|
@Override
|
||||||
public void increment() {
|
public void increment() {
|
||||||
Pair temp;
|
Pair temp;
|
||||||
lock.lock();
|
lock.lock();
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
package concurrency;//: concurrency/FastSimulation.java
|
package concurrency;//: concurrency/FastSimulation.java
|
||||||
|
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
import java.util.concurrent.atomic.*;
|
import java.util.concurrent.atomic.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import static net.mindview.util.Print.*;
|
import static net.mindview.util.Print.*;
|
||||||
|
|
||||||
public class FastSimulation {
|
public class FastSimulation {
|
||||||
@@ -11,18 +13,20 @@ public class FastSimulation {
|
|||||||
static final AtomicInteger[][] GRID =
|
static final AtomicInteger[][] GRID =
|
||||||
new AtomicInteger[N_ELEMENTS][N_GENES];
|
new AtomicInteger[N_ELEMENTS][N_GENES];
|
||||||
static Random rand = new Random(47);
|
static Random rand = new Random(47);
|
||||||
|
|
||||||
static class Evolver implements Runnable {
|
static class Evolver implements Runnable {
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
while(!Thread.interrupted()) {
|
while (!Thread.interrupted()) {
|
||||||
// Randomly select an element to work on:
|
// Randomly select an element to work on:
|
||||||
int element = rand.nextInt(N_ELEMENTS);
|
int element = rand.nextInt(N_ELEMENTS);
|
||||||
for(int i = 0; i < N_GENES; i++) {
|
for (int i = 0; i < N_GENES; i++) {
|
||||||
int previous = element - 1;
|
int previous = element - 1;
|
||||||
if(previous < 0) {
|
if (previous < 0) {
|
||||||
previous = N_ELEMENTS - 1;
|
previous = N_ELEMENTS - 1;
|
||||||
}
|
}
|
||||||
int next = element + 1;
|
int next = element + 1;
|
||||||
if(next >= N_ELEMENTS) {
|
if (next >= N_ELEMENTS) {
|
||||||
next = 0;
|
next = 0;
|
||||||
}
|
}
|
||||||
int oldvalue = GRID[element][i].get();
|
int oldvalue = GRID[element][i].get();
|
||||||
@@ -30,7 +34,7 @@ public class FastSimulation {
|
|||||||
int newvalue = oldvalue +
|
int newvalue = oldvalue +
|
||||||
GRID[previous][i].get() + GRID[next][i].get();
|
GRID[previous][i].get() + GRID[next][i].get();
|
||||||
newvalue /= 3; // Average the three values
|
newvalue /= 3; // Average the three values
|
||||||
if(!GRID[element][i]
|
if (!GRID[element][i]
|
||||||
.compareAndSet(oldvalue, newvalue)) {
|
.compareAndSet(oldvalue, newvalue)) {
|
||||||
// Policy here to deal with failure. Here, we
|
// Policy here to deal with failure. Here, we
|
||||||
// just report it and ignore it; our model
|
// just report it and ignore it; our model
|
||||||
@@ -41,14 +45,15 @@ public class FastSimulation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
ExecutorService exec = Executors.newCachedThreadPool();
|
ExecutorService exec = Executors.newCachedThreadPool();
|
||||||
for(int i = 0; i < N_ELEMENTS; i++) {
|
for (int i = 0; i < N_ELEMENTS; i++) {
|
||||||
for(int j = 0; j < N_GENES; j++) {
|
for (int j = 0; j < N_GENES; j++) {
|
||||||
GRID[i][j] = new AtomicInteger(rand.nextInt(1000));
|
GRID[i][j] = new AtomicInteger(rand.nextInt(1000));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(int i = 0; i < N_EVOLVERS; i++) {
|
for (int i = 0; i < N_EVOLVERS; i++) {
|
||||||
exec.execute(new Evolver());
|
exec.execute(new Evolver());
|
||||||
}
|
}
|
||||||
TimeUnit.SECONDS.sleep(5);
|
TimeUnit.SECONDS.sleep(5);
|
||||||
|
|||||||
@@ -5,12 +5,20 @@ public class Fat {
|
|||||||
private volatile double d; // Prevent optimization
|
private volatile double d; // Prevent optimization
|
||||||
private static int counter = 0;
|
private static int counter = 0;
|
||||||
private final int id = counter++;
|
private final int id = counter++;
|
||||||
|
|
||||||
public Fat() {
|
public Fat() {
|
||||||
// Expensive, interruptible operation:
|
// Expensive, interruptible operation:
|
||||||
for(int i = 1; i < 10000; i++) {
|
for (int i = 1; i < 10000; i++) {
|
||||||
d += (Math.PI + Math.E) / (double)i;
|
d += (Math.PI + Math.E) / (double) i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public void operation() { System.out.println(this); }
|
|
||||||
public String toString() { return "Fat id: " + id; }
|
public void operation() {
|
||||||
|
System.out.println(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Fat id: " + id;
|
||||||
|
}
|
||||||
} ///:~
|
} ///:~
|
||||||
|
|||||||
@@ -1,25 +1,26 @@
|
|||||||
package concurrency;//: concurrency/FixedDiningPhilosophers.java
|
package concurrency;//: concurrency/FixedDiningPhilosophers.java
|
||||||
// Dining philosophers without deadlock.
|
// Dining philosophers without deadlock.
|
||||||
// {Args: 5 5 timeout}
|
// {Args: 5 5 timeout}
|
||||||
|
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
|
|
||||||
public class FixedDiningPhilosophers {
|
public class FixedDiningPhilosophers {
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
int ponder = 5;
|
int ponder = 5;
|
||||||
if(args.length > 0) {
|
if (args.length > 0) {
|
||||||
ponder = Integer.parseInt(args[0]);
|
ponder = Integer.parseInt(args[0]);
|
||||||
}
|
}
|
||||||
int size = 5;
|
int size = 5;
|
||||||
if(args.length > 1) {
|
if (args.length > 1) {
|
||||||
size = Integer.parseInt(args[1]);
|
size = Integer.parseInt(args[1]);
|
||||||
}
|
}
|
||||||
ExecutorService exec = Executors.newCachedThreadPool();
|
ExecutorService exec = Executors.newCachedThreadPool();
|
||||||
Chopstick[] sticks = new Chopstick[size];
|
Chopstick[] sticks = new Chopstick[size];
|
||||||
for(int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
sticks[i] = new Chopstick();
|
sticks[i] = new Chopstick();
|
||||||
}
|
}
|
||||||
for(int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
if(i < (size-1)) {
|
if (i < (size - 1)) {
|
||||||
exec.execute(new Philosopher(
|
exec.execute(new Philosopher(
|
||||||
sticks[i], sticks[i + 1], i, ponder));
|
sticks[i], sticks[i + 1], i, ponder));
|
||||||
} else {
|
} else {
|
||||||
@@ -27,7 +28,7 @@ public class FixedDiningPhilosophers {
|
|||||||
sticks[0], sticks[i], i, ponder));
|
sticks[0], sticks[i], i, ponder));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(args.length == 3 && args[2].equals("timeout")) {
|
if (args.length == 3 && args[2].equals("timeout")) {
|
||||||
TimeUnit.SECONDS.sleep(5);
|
TimeUnit.SECONDS.sleep(5);
|
||||||
} else {
|
} else {
|
||||||
System.out.println("Press 'Enter' to quit");
|
System.out.println("Press 'Enter' to quit");
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
package concurrency;//: concurrency/FixedThreadPool.java
|
package concurrency;//: concurrency/FixedThreadPool.java
|
||||||
|
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
|
|
||||||
public class FixedThreadPool {
|
public class FixedThreadPool {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
// Constructor argument is number of threads:
|
// Constructor argument is number of threads:
|
||||||
ExecutorService exec = Executors.newFixedThreadPool(5);
|
ExecutorService exec = Executors.newFixedThreadPool(5);
|
||||||
for(int i = 0; i < 5; i++) {
|
for (int i = 0; i < 5; i++) {
|
||||||
exec.execute(new LiftOff());
|
exec.execute(new LiftOff());
|
||||||
}
|
}
|
||||||
exec.shutdown();
|
exec.shutdown();
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package concurrency;//: concurrency/GreenhouseScheduler.java
|
|||||||
// Rewriting innerclasses/GreenhouseController.java
|
// Rewriting innerclasses/GreenhouseController.java
|
||||||
// to use a ScheduledThreadPoolExecutor.
|
// to use a ScheduledThreadPoolExecutor.
|
||||||
// {Args: 5000}
|
// {Args: 5000}
|
||||||
|
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@@ -9,23 +10,30 @@ public class GreenhouseScheduler {
|
|||||||
private volatile boolean light = false;
|
private volatile boolean light = false;
|
||||||
private volatile boolean water = false;
|
private volatile boolean water = false;
|
||||||
private String thermostat = "Day";
|
private String thermostat = "Day";
|
||||||
|
|
||||||
public synchronized String getThermostat() {
|
public synchronized String getThermostat() {
|
||||||
return thermostat;
|
return thermostat;
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void setThermostat(String value) {
|
public synchronized void setThermostat(String value) {
|
||||||
thermostat = value;
|
thermostat = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
ScheduledThreadPoolExecutor scheduler =
|
ScheduledThreadPoolExecutor scheduler =
|
||||||
new ScheduledThreadPoolExecutor(10);
|
new ScheduledThreadPoolExecutor(10);
|
||||||
|
|
||||||
public void schedule(Runnable event, long delay) {
|
public void schedule(Runnable event, long delay) {
|
||||||
scheduler.schedule(event,delay,TimeUnit.MILLISECONDS);
|
scheduler.schedule(event, delay, TimeUnit.MILLISECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void
|
public void
|
||||||
repeat(Runnable event, long initialDelay, long period) {
|
repeat(Runnable event, long initialDelay, long period) {
|
||||||
scheduler.scheduleAtFixedRate(
|
scheduler.scheduleAtFixedRate(
|
||||||
event, initialDelay, period, TimeUnit.MILLISECONDS);
|
event, initialDelay, period, TimeUnit.MILLISECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
class LightOn implements Runnable {
|
class LightOn implements Runnable {
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
// Put hardware control code here to
|
// Put hardware control code here to
|
||||||
// physically turn on the light.
|
// physically turn on the light.
|
||||||
@@ -33,7 +41,9 @@ public class GreenhouseScheduler {
|
|||||||
light = true;
|
light = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class LightOff implements Runnable {
|
class LightOff implements Runnable {
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
// Put hardware control code here to
|
// Put hardware control code here to
|
||||||
// physically turn off the light.
|
// physically turn off the light.
|
||||||
@@ -41,62 +51,81 @@ public class GreenhouseScheduler {
|
|||||||
light = false;
|
light = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class WaterOn implements Runnable {
|
class WaterOn implements Runnable {
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
// Put hardware control code here.
|
// Put hardware control code here.
|
||||||
System.out.println("Turning greenhouse water on");
|
System.out.println("Turning greenhouse water on");
|
||||||
water = true;
|
water = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class WaterOff implements Runnable {
|
class WaterOff implements Runnable {
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
// Put hardware control code here.
|
// Put hardware control code here.
|
||||||
System.out.println("Turning greenhouse water off");
|
System.out.println("Turning greenhouse water off");
|
||||||
water = false;
|
water = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ThermostatNight implements Runnable {
|
class ThermostatNight implements Runnable {
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
// Put hardware control code here.
|
// Put hardware control code here.
|
||||||
System.out.println("Thermostat to night setting");
|
System.out.println("Thermostat to night setting");
|
||||||
setThermostat("Night");
|
setThermostat("Night");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ThermostatDay implements Runnable {
|
class ThermostatDay implements Runnable {
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
// Put hardware control code here.
|
// Put hardware control code here.
|
||||||
System.out.println("Thermostat to day setting");
|
System.out.println("Thermostat to day setting");
|
||||||
setThermostat("Day");
|
setThermostat("Day");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Bell implements Runnable {
|
class Bell implements Runnable {
|
||||||
public void run() { System.out.println("Bing!"); }
|
@Override
|
||||||
|
public void run() {
|
||||||
|
System.out.println("Bing!");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class Terminate implements Runnable {
|
class Terminate implements Runnable {
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
System.out.println("Terminating");
|
System.out.println("Terminating");
|
||||||
scheduler.shutdownNow();
|
scheduler.shutdownNow();
|
||||||
// Must start a separate task to do this job,
|
// Must start a separate task to do this job,
|
||||||
// since the scheduler has been shut down:
|
// since the scheduler has been shut down:
|
||||||
new Thread() {
|
new Thread() {
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
for(DataPoint d : data) {
|
for (DataPoint d : data) {
|
||||||
System.out.println(d);
|
System.out.println(d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.start();
|
}.start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// New feature: data collection
|
// New feature: data collection
|
||||||
static class DataPoint {
|
static class DataPoint {
|
||||||
final Calendar time;
|
final Calendar time;
|
||||||
final float temperature;
|
final float temperature;
|
||||||
final float humidity;
|
final float humidity;
|
||||||
|
|
||||||
public DataPoint(Calendar d, float temp, float hum) {
|
public DataPoint(Calendar d, float temp, float hum) {
|
||||||
time = d;
|
time = d;
|
||||||
temperature = temp;
|
temperature = temp;
|
||||||
humidity = hum;
|
humidity = hum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return time.getTime() +
|
return time.getTime() +
|
||||||
String.format(
|
String.format(
|
||||||
@@ -104,11 +133,14 @@ public class GreenhouseScheduler {
|
|||||||
temperature, humidity);
|
temperature, humidity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Calendar lastTime = Calendar.getInstance();
|
private Calendar lastTime = Calendar.getInstance();
|
||||||
|
|
||||||
{ // Adjust date to the half hour
|
{ // Adjust date to the half hour
|
||||||
lastTime.set(Calendar.MINUTE, 30);
|
lastTime.set(Calendar.MINUTE, 30);
|
||||||
lastTime.set(Calendar.SECOND, 00);
|
lastTime.set(Calendar.SECOND, 00);
|
||||||
}
|
}
|
||||||
|
|
||||||
private float lastTemp = 65.0f;
|
private float lastTemp = 65.0f;
|
||||||
private int tempDirection = +1;
|
private int tempDirection = +1;
|
||||||
private float lastHumidity = 50.0f;
|
private float lastHumidity = 50.0f;
|
||||||
@@ -116,21 +148,23 @@ public class GreenhouseScheduler {
|
|||||||
private Random rand = new Random(47);
|
private Random rand = new Random(47);
|
||||||
List<DataPoint> data = Collections.synchronizedList(
|
List<DataPoint> data = Collections.synchronizedList(
|
||||||
new ArrayList<DataPoint>());
|
new ArrayList<DataPoint>());
|
||||||
|
|
||||||
class CollectData implements Runnable {
|
class CollectData implements Runnable {
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
System.out.println("Collecting data");
|
System.out.println("Collecting data");
|
||||||
synchronized(GreenhouseScheduler.this) {
|
synchronized (GreenhouseScheduler.this) {
|
||||||
// Pretend the interval is longer than it is:
|
// Pretend the interval is longer than it is:
|
||||||
lastTime.set(Calendar.MINUTE,
|
lastTime.set(Calendar.MINUTE,
|
||||||
lastTime.get(Calendar.MINUTE) + 30);
|
lastTime.get(Calendar.MINUTE) + 30);
|
||||||
// One in 5 chances of reversing the direction:
|
// One in 5 chances of reversing the direction:
|
||||||
if(rand.nextInt(5) == 4) {
|
if (rand.nextInt(5) == 4) {
|
||||||
tempDirection = -tempDirection;
|
tempDirection = -tempDirection;
|
||||||
}
|
}
|
||||||
// Store previous value:
|
// Store previous value:
|
||||||
lastTemp = lastTemp +
|
lastTemp = lastTemp +
|
||||||
tempDirection * (1.0f + rand.nextFloat());
|
tempDirection * (1.0f + rand.nextFloat());
|
||||||
if(rand.nextInt(5) == 4) {
|
if (rand.nextInt(5) == 4) {
|
||||||
humidityDirection = -humidityDirection;
|
humidityDirection = -humidityDirection;
|
||||||
}
|
}
|
||||||
lastHumidity = lastHumidity +
|
lastHumidity = lastHumidity +
|
||||||
@@ -138,11 +172,12 @@ public class GreenhouseScheduler {
|
|||||||
// Calendar must be cloned, otherwise all
|
// Calendar must be cloned, otherwise all
|
||||||
// DataPoints hold references to the same lastTime.
|
// DataPoints hold references to the same lastTime.
|
||||||
// For a basic object like Calendar, clone() is OK.
|
// For a basic object like Calendar, clone() is OK.
|
||||||
data.add(new DataPoint((Calendar)lastTime.clone(),
|
data.add(new DataPoint((Calendar) lastTime.clone(),
|
||||||
lastTemp, lastHumidity));
|
lastTemp, lastHumidity));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
GreenhouseScheduler gh = new GreenhouseScheduler();
|
GreenhouseScheduler gh = new GreenhouseScheduler();
|
||||||
gh.schedule(gh.new Terminate(), 5000);
|
gh.schedule(gh.new Terminate(), 5000);
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user