《Java多线程编程核心技术》读后感(六)
多线程的死锁
package Second; public class DealThread implements Runnable { public String username; public Object lock1 = new Object(); public Object lock2 = new Object(); public void setFlag(String username) { this.username = username; } @Override public void run() { if (username.equals("a")) { synchronized (lock1) { try { System.out.println("username = " + username); Thread.sleep(3000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } synchronized (lock2) { System.out.println("按lock1->lock2代码顺序执行了"); } } } if (username.equals("b")) { synchronized (lock2) { try { System.out.println("username = " + username); Thread.sleep(3000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } synchronized (lock1) { System.out.println("按lock2->lock1代码顺序执行了"); } } } } }
只要互相等待对方释放锁就有可能出现死锁
内置类与静态内置类
package Second; public class PublicClass { private String username; private String password; class PrivateClass { private String age; private String address; public String getAge() { return age; } public void setAge(String age) { this.age = age; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public void printPublicProperty() { System.out.println(username + " " + password); } } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
package Second; import Second.PublicClass.PrivateClass; public class Run { public static void main(String[] args) { PublicClass publicClass = new PublicClass(); publicClass.setUsername("usernameValue"); publicClass.setPassword("passwordValue"); System.out.println(publicClass.getUsername() + " " + publicClass.getPassword()); PrivateClass privateClass = publicClass.new PrivateClass(); privateClass.setAge("ageValue"); privateClass.setAddress("addressValue"); System.out.println(privateClass.getAge() + " " + privateClass.getAddress()); } }
package Second; public class PublicClass { static private String username; static private String password; static class PrivateClass { private String age; private String address; public String getAge() { return age; } public void setAge(String age) { this.age = age; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public void printPublicProperty() { System.out.println(username + " " + password); } } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
package Second; import Second.PublicClass.PrivateClass; public class Run { public static void main(String[] args) { PublicClass publicClass = new PublicClass(); publicClass.setUsername("usernameValue"); publicClass.setPassword("passwordValue"); System.out.println(publicClass.getUsername() + " " + publicClass.getPassword()); PrivateClass privateClass = new PrivateClass(); privateClass.setAge("ageValue"); privateClass.setAddress("addressValue"); System.out.println(privateClass.getAge() + " " + privateClass.getAddress()); } }
内置类与同步:实验1
本实验案例是在内置类中有两个同步方法,但使用的却是不同的锁,打印的结果也是异步的。
package Second; public class OutClass { static class Inner { public void method1() { synchronized ("其他的鎖") { for (int i = 1; i <= 10; i++) { System.out.println(Thread.currentThread().getName() + " i=" + i); try { Thread.sleep(100); } catch (InterruptedException e) { } } } } public synchronized void method2() { for (int i = 11; i <= 20; i++) { System.out.println(Thread.currentThread().getName() + " i=" + i); try { Thread.sleep(100); } catch (InterruptedException e) { } } } } }
package Second; import Second.OutClass.Inner; public class Run { public static void main(String[] args) { final Inner inner = new Inner(); Thread t1 = new Thread(new Runnable() { public void run() { inner.method1(); } }, "A"); Thread t2 = new Thread(new Runnable() { public void run() { inner.method2(); } }, "B"); t1.start(); t2.start(); } }
由于持有不同的“”对象监视器“”,所以打印结果就是乱序的
内置类与同步:实验2
锁对象的改变
package Second; public class MyService { private String lock = "123"; public void testMethod() { try { synchronized (lock) { System.out.println(Thread.currentThread().getName() + " begin " + System.currentTimeMillis()); lock = "456"; Thread.sleep(2000); System.out.println(Thread.currentThread().getName() + " end " + System.currentTimeMillis()); } } catch (InterruptedException e) { e.printStackTrace(); } } }
package Second; public class ThreadA extends Thread { private MyService service; public ThreadA(MyService service) { super(); this.service = service; } @Override public void run() { service.testMethod(); } }
package Second; public class ThreadB extends Thread { private MyService service; public ThreadB(MyService service) { super(); this.service = service; } @Override public void run() { service.testMethod(); } }
package Second; public class Run1 { public static void main(String[] args) throws InterruptedException { MyService service = new MyService(); ThreadA a = new ThreadA(service); a.setName("A"); ThreadB b = new ThreadB(service); b.setName("B"); a.start(); Thread.sleep(50); b.start(); } }
因为50毫秒过后线程B获得的锁时“”456“”
package Second; public class Run2 { public static void main(String[] args) throws InterruptedException { MyService service = new MyService(); ThreadA a = new ThreadA(service); a.setName("A"); ThreadB b = new ThreadB(service); b.setName("B"); a.start(); b.start(); } }
线程AB持有的锁都是“”123“”,虽然将锁改成了“”456“”,但结果还是同步的,因为A和B共同争抢的锁时“”123“”
package Second; public class Userinfo { private String username; private String password; public Userinfo() { super(); } public Userinfo(String username, String password) { super(); this.username = username; this.password = password; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
package Second; public class Service { public void serviceMethodA(Userinfo userinfo) { synchronized (userinfo) { try { System.out.println(Thread.currentThread().getName()); userinfo.setUsername("abcabcabc"); Thread.sleep(3000); System.out.println("end! time=" + System.currentTimeMillis()); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
package Second; public class ThreadA extends Thread { private Service service; private Userinfo userinfo; public ThreadA(Service service, Userinfo userinfo) { super(); this.service = service; this.userinfo = userinfo; } @Override public void run() { service.serviceMethodA(userinfo); } }
package Second; public class ThreadB extends Thread { private Service service; private Userinfo userinfo; public ThreadB(Service service, Userinfo userinfo) { super(); this.service = service; this.userinfo = userinfo; } @Override public void run() { service.serviceMethodA(userinfo); } }
package Second; public class Run { public static void main(String[] args) { try { Service service = new Service(); Userinfo userinfo = new Userinfo(); ThreadA a = new ThreadA(service, userinfo); a.setName("a"); a.start(); Thread.sleep(50); ThreadB b = new ThreadB(service, userinfo); b.setName("b"); b.start(); } catch (InterruptedException e) { e.printStackTrace(); } } }
上述实验表明:只要对象不变,即使对象的属性被改变,运行的结果还是同步。
posted on 2017-11-16 22:19 Michael2397 阅读(394) 评论(1) 编辑 收藏 举报