synchronized关键字

来源:互联网 发布:大数据挖掘工程师招聘 编辑:程序博客网 时间:2024/06/06 16:31

开启两个线程,分别打印两种字符串,字符串按一个一个的字母输出.如果不加锁,则会出现打印一半字符串时,CPU分配时间片到另一个线程上打印,造成打印一半的现象.如下测试:

/** * synchronized关键字 */public class SyncTest {    public static void main(String[] args) {        SyncTest syncTest = new SyncTest();        syncTest.init();    }    private void init() {        final Outputer outputer = new Outputer();        //创建两个线程,分别输入不同的字符串        new Thread(new Runnable() {            public void run() {                while (true) {                    try {                        Thread.sleep(10);                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                    outputer.out1("meiran");                }            }        }).start();        new Thread(new Runnable() {            public void run() {                while (true) {                    try {                        Thread.sleep(10);                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                    outputer.out2("zhoutong");                }            }        }).start();    }    class Outputer {        /**         * 对调用的对象加锁(因为调用的对象为同一对象)         *         * @param name         */        public void out1(String name) {            int length = name.length();            synchronized (this) {                for (int i = 0; i < length; i++) {                    System.out.print(name.charAt(i));                }                System.out.println("");            }        }        /**         * 对方法加锁(对调用此方法的对象加锁)         *         * @param name         */        public synchronized void out2(String name) {            int length = name.length();            for (int i = 0; i < length; i++) {                System.out.print(name.charAt(i));            }            System.out.println("");        }    }}

以上代码需要说明的问题:

1、对象加锁,使用this关键字的意思是:对调用该方法的对象加锁。

2、方法上加synchronized与使用this关键字等价。

3、内部匿名类中使用局部变量,局部变量需为final的。

4、static方法访问非static的内部类,因非static的内部类可以访问外部类的成员变量,说明非static的内部类的对象需由外部类的对象调用,所以需加非static的内部类的对象放入非static的内部类的方法中,由static方法调用非static的方法实现。

5、static方法调非static方法需要创建对象。


测试用例2:

/** * 理解static方法的锁对象是谁 */public class SyncTest2 {    public static void main(String[] args) {        SyncTest2 syncTest = new SyncTest2();        syncTest.init();    }    private void init() {        final Outputer outputer = new Outputer();        //创建两个线程,分别输入不同的字符串        new Thread(new Runnable() {            public void run() {                while (true) {                    try {                        Thread.sleep(10);                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                    outputer.out1("meiran");                }            }        }).start();        new Thread(new Runnable() {            public void run() {                while (true) {                    try {                        Thread.sleep(10);                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                    outputer.out2("zhoutong");                }            }        }).start();    }    static class Outputer {        /**         * 对字节码类对象加锁         *         * @param name         */        public void out1(String name) {            int length = name.length();            synchronized (Outputer.class) {                for (int i = 0; i < length; i++) {                    System.out.print(name.charAt(i));                }                System.out.println("");            }        }        /**         * 静态方法加锁是对字节码类对象加锁         *         * @param name         */        public static synchronized void out2(String name) {            int length = name.length();            for (int i = 0; i < length; i++) {                System.out.print(name.charAt(i));            }            System.out.println("");        }    }}


以上代码需要说明的问题:

1、static方法的锁对象是字节码文件的对象。

2、内部类不能有static方法。必须定义为静态内部类,相当于顶级类。

0 0
原创粉丝点击