zoukankan      html  css  js  c++  java
  • Java多线程与并发库高级应用-传统线程互斥技术

     线程安全问题:

      多个线程操作同一份数据的时候,有可能会出现线程安全问题。可以用银行转账来解释。

    模拟线程安全问题

    /**
     * 启动两个线程分别打印两个名字,名字按照字符一个一个打印
     * 
     * @author Administrator
     * 
     */
    public class TraditionalThreadSynchronized {
    
        public static void main(String[] args) {
            new TraditionalThreadSynchronized().init();
        }
    
        public void init() {
            final Outputer outputer = new Outputer();// 内部类访问成员外部变量需要加final
            new Thread(new Runnable() {
    
                @Override
                public void run() {
                    while (true) {
                        try {
                            Thread.sleep(10);
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        outputer.output("aaaaa");
                    }
                }
            }).start();
    
            new Thread(new Runnable() {
    
                @Override
                public void run() {
                    while (true) {
                        try {
                            Thread.sleep(10);
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        outputer.output("bbb");
                    }
                }
            }).start();
        }
    
        class Outputer {
            public void output(String name) {
                int len = name.length();
                synchronized(this){   //使用静态代码块进行同步
                    for (int i = 0; i < len; i++) {
                        char c = name.charAt(i);
                        System.out.print(c);
                    }
                }
                System.out.println();
            }
        }
    
    }

     

     以上涉及两个问题:

      内部类中使用外部类的成员变量需要加final 

      静态方法中不能 new 内部类的实例对象,why?

        内部类的重要特点,由于内部类可以访问外部类的成员变量,意味着外部类有了实例对象,静态方法执行时有不一定有外部类的实例对象初始化。所以互相矛盾。

    以上代码还可以有一种写法

    class Outputer {
            public synchronized void output(String name) {
                int len = name.length();
    //            synchronized(this){   //使用静态代码块进行同步
                    for (int i = 0; i < len; i++) {
                        char c = name.charAt(i);
                        System.out.print(c);
                    }
    //            }
                System.out.println();
            }
        }

     直接将synchronized写法方法声明中,使用静态方法方式,内部使用的对象还是this

    static class Outputer {
            public void output(String name) {
                int len = name.length();
                synchronized(Outputer.class){   //使用同步代码块进行同步  要想使output与output3进行同步,这里就不能使用this了,可以使用类的字节码
                    for (int i = 0; i < len; i++) {
                        char c = name.charAt(i);
                        System.out.print(c);
                    }
                }
                System.out.println();
            }
            public synchronized void output2(String name) {  //同步方法
                int len = name.length();
                for (int i = 0; i < len; i++) {
                    char c = name.charAt(i);
                    System.out.print(c);
                }
                System.out.println();
            }
            public static synchronized void output3(String name) {  //同步方法
                int len = name.length();
                for (int i = 0; i < len; i++) {
                    char c = name.charAt(i);
                    System.out.print(c);
                }
                System.out.println();
            }
        }

    synchronized关键字后边是要检查一把锁对象, 要在某段代码上实现同步,必须使用同一把锁挡住这些线程,不同锁是挡不住的。

    静态方法中不能跟this关联,跟类的字节码进行关联

  • 相关阅读:
    React Native之通知栏消息提示(ios)
    前端知识点总结(HTML)
    React Native之通知栏消息提示(android)
    微信QQ打开网页时提示用浏览器打开
    微信小程序开发的基本流程
    React Native之code-push的热更新(ios android)
    ES7的新特性
    如何将本地项目上传到码云
    找不到或无法加载主类(Could not find or load main class)
    Java代码操作HDFS
  • 原文地址:https://www.cnblogs.com/wq3435/p/6028889.html
Copyright © 2011-2022 走看看