Java多线程与并发库高级应用-传统线程互斥技术
发布日期:2021-07-12 08:49:35 浏览次数:5 分类:技术文章

本文共 3298 字,大约阅读时间需要 10 分钟。

 线程安全问题:

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

模拟线程安全问题

 

 

 

/** * 启动两个线程分别打印两个名字,名字按照字符一个一个打印 *  * @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关联,跟类的字节码进行关联

 

转载于:https://www.cnblogs.com/wq3435/p/6028889.html

转载地址:https://blog.csdn.net/ankan7400/article/details/102088969 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:Java多线程与并发库高级应用-传统线程同步通信技术
下一篇:Java多线程与并发库高级应用-传统定时器技术回顾

发表评论

最新留言

留言是一种美德,欢迎回访!
[***.207.175.100]2024年04月15日 02时11分09秒