模式1--SingleThreadExecution
来至《java多线程设计模式》
一、方法:用synchronized方法,每次只让一个通过。
public class UserThread extends Thread { private final Gate gate; private final String myname; private final String myaddress; public UserThread(Gate gate, String myname, String myaddress) { this.gate = gate; this.myname = myname; this.myaddress = myaddress; } public void run() { System.out.println(myname + " BEGIN"); while (true) { gate.pass(myname, myaddress); } } }
public class Gate { private int counter = 0; private String name = "Nobody"; private String address = "Nowhere"; public void pass(String name, String address) { this.counter++; this.name = name; this.address = address; check(); } public String toString() { return "No." + counter + ": " + name + ", " + address; } private void check() { if (name.charAt(0) != address.charAt(0)) { System.out.println("***** BROKEN ***** " + toString()); } } }
每次只让一个通过:
public class Gate { private int counter = 0; private String name = "Nobody"; private String address = "Nowhere"; public synchronized void pass(String name, String address) { this.counter++; this.name = name; this.address = address; check(); } public synchronized String toString() { return "No." + counter + ": " + name + ", " + address; } private void check() { if (name.charAt(0) != address.charAt(0)) { System.out.println("***** BROKEN ***** " + toString()); } } }
二、让错误更容易发生:在延迟占用临界区的时间:
public class Gate { private int counter = 0; private String name = "Nobody"; private String address = "Nowhere"; public void pass(String name, String address) { this.counter++; this.name = name; try { Thread.sleep(1000); } catch (InterruptedException e) { } this.address = address; check(); } public String toString() { return "No." + counter + ": " + name + ", " + address; } private void check() { if (name.charAt(0) != address.charAt(0)) { System.out.println("***** BROKEN ***** " + toString()); } } }
三、避免死锁:
(1)多个共享资源
(2)未释放锁定就去试图锁定另外一个
(3)获取A--》获取B,或获取B--》获取A,A/B的获取顺序对等,没有优先级
只要破坏以上一个即可避免死锁:
public class Main { public static void main(String[] args) { System.out.println("Testing EaterThread, hit CTRL+C to exit."); Tool spoon = new Tool("Spoon"); Tool fork = new Tool("Fork"); new EaterThread("Alice", spoon, fork).start(); new EaterThread("Bobby", fork, spoon).start(); } }
破坏(3):
public class Main {
public static void main(String[] args) {
System.out.println("Testing EaterThread, hit CTRL+C to exit.");
Tool spoon = new Tool("Spoon");
Tool fork = new Tool("Fork");
new EaterThread("Alice", spoon, fork).start();
new EaterThread("Bobby", spoon, fork).start();
}
}
都先去获取spoon再去获取fork。
破坏(1):
修改为一个共享资源:
public class Main { public static void main(String[] args) { System.out.println("Testing EaterThread, hit CTRL+C to exit."); Tool spoon = new Tool("Spoon"); Tool fork = new Tool("Fork"); Pair pair = new Pair(spoon, fork); new EaterThread("Alice", pair).start(); new EaterThread("Bobby", pair).start(); } }
public void eat() { synchronized (pair) { System.out.println(name + " takes up " + pair + "."); System.out.println(name + " is eating now, yam yam!"); System.out.println(name + " puts down " + pair + "."); } }
浙公网安备 33010602011771号