JAVA多线程安全之构造函数
2017-08-28 18:00
519 查看
在一般情况下,Java的构造函数总结如下:
在构造函数一开始,this就是可用的了。
构造函数和普通函数一样,并不是默认被synchronized 的,有可能出现同步问题。
如果构造函数中访问静态变量的话,必须同步这个静态变量,否则一定会出问题。
如果只访问成员变量的话,无论在任何线程中,每一次构造函数被调用,其中的成员变量都是新建造出来的,因此不可能出现说在这个线程中运行的构造函数 会访问到另一个线程中运行的构造函数中的成员变量的情况,因此这就是我所说的“访问成员变量不可能出现同步问题”的意思。 这里的前提是,两个线程中都运行的是构造函数,而不是其他方法(例如start所启动的run方法。)。
如果在构造函数中,把this交给其他的线程去访问,则其他线程可能在this实例还未初始化完毕时就访问了其中的变量,这有可能产生同步问题。这时需要显式同步this对象。
构造方法不需要同步化,因为它只可能发生在一个线程里,在构造方法返回值前没有其他线程可以使用该对象。(一个线程已经在构造方法里面了,另外一个线程也可以调用构造方法,第一个线程里面生成的对象和第二个线程里面生成的对象是不同的对象。)
构造方法里面使用的静态属性,是需要同步的,构造方法不执行完成其他线程是没有办法访问该对象的,但是类对象是已经存在的,可以被多个线程访问:如
子类可以置换掉父类的同步方法,使它同步或不同步。这就是说,子类的方法不继承其父类方法的特性。父类的方法不改变,如果明显地调用父类的同步方法,那么这个将是同步调用的。
如果在构造函数中,把this交给其他的线程去访问,则其他线程可能在this实例还未初始化完毕时就访问了其中的变量,这有可能产生同步问题。这时需要显式同步this对象。
在构造函数一开始,this就是可用的了。
构造函数和普通函数一样,并不是默认被synchronized 的,有可能出现同步问题。
如果构造函数中访问静态变量的话,必须同步这个静态变量,否则一定会出问题。
如果只访问成员变量的话,无论在任何线程中,每一次构造函数被调用,其中的成员变量都是新建造出来的,因此不可能出现说在这个线程中运行的构造函数 会访问到另一个线程中运行的构造函数中的成员变量的情况,因此这就是我所说的“访问成员变量不可能出现同步问题”的意思。 这里的前提是,两个线程中都运行的是构造函数,而不是其他方法(例如start所启动的run方法。)。
如果在构造函数中,把this交给其他的线程去访问,则其他线程可能在this实例还未初始化完毕时就访问了其中的变量,这有可能产生同步问题。这时需要显式同步this对象。
构造方法不需要同步化,因为它只可能发生在一个线程里,在构造方法返回值前没有其他线程可以使用该对象。(一个线程已经在构造方法里面了,另外一个线程也可以调用构造方法,第一个线程里面生成的对象和第二个线程里面生成的对象是不同的对象。)
构造方法里面使用的静态属性,是需要同步的,构造方法不执行完成其他线程是没有办法访问该对象的,但是类对象是已经存在的,可以被多个线程访问:如
public class Test { public static int id=0; public int c; public Test() { c=id; System.out.println(Thread.currentThread().getName() + "到达"); try{ Thread.sleep(100); }catch(InterruptedException e){ e.printStackTrace(); } id++; } public static void main(String [] args){ class ThreadTst extends Thread { public void run(){ Test test=new Test(); System.out.println(test.c); } } new ThreadTst().start(); new ThreadTst().start(); } }/* output Thread-0到达 Thread-1到达 0 0 */ public class Test { public static int id=0; public int c; public Test() { synchronized(Test.class) { c=id; System.out.println(Thread.currentThread().getName() + "到达"); try{ Thread.sleep(100); }catch(InterruptedException e){ e.printStackTrace(); } id++; } } public static void main(String [] args){ class ThreadTst extends Thread { public void run(){ Test test=new Test(); System.out.println(test.c); } } new ThreadTst().start(); new ThreadTst().start(); } }
/* output Thread-0到达 0 Thread-1到达 1 */
子类可以置换掉父类的同步方法,使它同步或不同步。这就是说,子类的方法不继承其父类方法的特性。父类的方法不改变,如果明显地调用父类的同步方法,那么这个将是同步调用的。
如果在构造函数中,把this交给其他的线程去访问,则其他线程可能在this实例还未初始化完毕时就访问了其中的变量,这有可能产生同步问题。这时需要显式同步this对象。
class A { int i; public A () { synchronized(this) { new Snippet(this); try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } i = 2; } } } public class Snippet extends Thread { A a; public Snippet(A a) { this.a = a; start(); } public void run() { synchronized(a) { System.out.println(a.i); } } public static void main(String[] args) { new A(); } }
/* Output: 2 *///:~
相关文章推荐
- [Java]Java的静态构造函数 多线程下安全的单例模式
- Java多线程安全之对象的发布和溢出、线程封闭详解
- java中面对多线程安全问题,用什么样的Map
- Java Tread多线程(2)多线程安全问题
- java中的多线程安全问题
- 【Java并发编程】之八:多线程环境中安全使用集合API(含代码)
- Java多线程安全的实现
- Java多线程总结之线程安全队列Queue
- Java——生产者消费者中多线程安全问题
- java 多线程 线程健康安全
- Java多线程总结之线程安全队列Queue
- Java多线程之线程安全与异步执行
- Java多线程安全问题
- Java 多线程 线程安全相关概念
- 【Java并发编程】之八:多线程环境中安全使用集合API(含代码)
- java多线程学习一线程安全之内存、synchronized、volatile
- 4000 java中多线程的安全问题以及解决办法(2)
- java---教你怎么判断多线程是否安全
- 设计模式——单例模式(Java)——考虑多线程环境下的线程安全问题
- Java多线程的安全