zoukankan      html  css  js  c++  java
  • 《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();
            }
    
        }
    }

    上述实验表明:只要对象不变,即使对象的属性被改变,运行的结果还是同步。

  • 相关阅读:
    NGUI的HUD Text的扩展插件学习--(HUDText)的使用
    C#设计模式:外观模式(Facade Pattern)
    NGUI的HUD Text的扩展插件学习--(UIFollowTarget)的使用
    NGUI的怎么在一个Gameobject(游戏物体)中调用另一个Gameobject(游戏物体)的脚本(C#)
    C#设计模式:组合模式(Composite Pattern)
    C#Contains方法的错误理解
    C#.NET动态页面静态化生成
    C++ primer plus读书笔记——第1章 预备知识
    如何判断一个数是2的幂
    C++将数值转换为string
  • 原文地址:https://www.cnblogs.com/Michael2397/p/7846844.html
Copyright © 2011-2022 走看看