`

多线程构造函数

 
阅读更多
http://hi.baidu.com/tengxiaofei001/item/a995a9269023c60b77272c00 写道
1. 在构造函数一开始,this就是可用的了。
2. 构造函数和普通函数一样,并不是默认被synchronized 的,有可能出现同步问题。
3. 如果构造函数中访问静态变量的话,必须同步这个静态变量,否则一定会出问题。
4. 如果只访问成员变量的话,无论在任何线程中,每一次构造函数被调用,其中的成员变量都是新建造出来的,因此不可能出现说在这个线程中运行的构造函数 会访问到另一个线程中运行的构造函数中的成员变量的情况,因此这就是我所说的“访问成员变量不可能出现同步问题”的意思。 这里的前提是,两个线程中都运行的是构造函数,而不是其他方法(例如start所启动的run方法。)。

4.如果在构造函数中,把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多线程开发中线程创建时多用到的创建方式(不同的构造函数)以及线程组相关的基础知识

    关于在类的构造函数和析构使用临界区函数导致的多线程死锁的一个经验之谈

    关于在类的构造函数和析构使用临界区函数导致的多线程死锁的一个经验之谈

    多线程并发查找.docx

    查找线程的构造函数形参如下所示: 数组名, 查找范围(起始下标、结束下标) 每个线程体在查找范围内顺序查找,并将该范围内所有找到的x的下标记录到共享的一个内存缓冲区。 要求共享缓冲区中的下标按升序存储。 ...

    使用DES和多线程等方法实现文件的加解密(C#)

    程序采用了DES的方式进行文件的加解密。 并采用多线程技术准确的将文件加解密进度显示在进度条上,使用构造函数实现各窗口间的参数传递!

    基于泛型的,高性能的,可指定构造函数及传入参数初始化的,线程安全的,扩展性非常高的传说中的对象池

    基于泛型的,高性能的,可指定构造函数及传入参数初始化的,线程安全的,扩展性非常高的传说中的对象池 详细看: http://blog.csdn.net/luyikk/archive/2010/05/10/5576550.aspx

    c++11多线程编程

    c++11多线程库的使用,主要介绍了thread类中的构造函数 join函数和detach函数的使用方式

    JAVA多线程编程详解-详细操作例子(转自CSDN)

    但是 Runnable 接口并没有任何对线程的支持,我们还必须创建 Thread 类的实例,这一点通过 Thread 类的构造函数public Thread(Runnable target);来实现。下面是一个例子: public class MyThread implements ...

    rk3588rk3588s使用c++多线程异步等优化c++实现源码(yolov5运行可达到135fps)+项目使用说明.zip

    rk3588rk3588s使用c++多线程异步等优化c++实现源码(yolov5运行可达到135fps)+项目使用说明.zip 【资源介绍】 该项目为c++实现, 大体改自rknpu2 使用线程池异步操作rknn模型, 提高rk3588/rk3588s的NPU使用率, 进而...

    基础深化和提高-Java多线程技术

    实现Runnable接口:创建一个类实现java.lang.Runnable接口,实现run()方法,并将该实现类传递给Thread类的构造函数中。然后创建Thread实例并启动线程。 java class MyRunnable implements Runnable { public void r

    Java多线程之并发工具类

    一、总论:在JDK中提供了几种并发工具类  1)CountDownLatch(同步倒数计数器:等待多线程...  CountDownLatch的构造函数接受一个int类的参数作为计数器,如果你想等待N个节点完成,那这里传入N.  2.countDown

    C++11并发编程:多线程std::thread

    C++11引入了thread类,大大降低了多线程使用的复杂度,原先使用多线程只能用系统的API,无法解决跨平台问题,一套代码平台移植,对应多线程代码也必须要修改。现在在C++11中只需使用语言层面的thread可以解决这个...

    PHP多线程之内部多线程实例分析

    本文实例分析了PHP多线程之内部多线程用法。分享给大家供大家参考。具体如下: 复制代码 代码如下:<?php class Http_MultiRequest {  //要并行抓取的url 列表  private $urls = array();  //curl 的选项  ...

    C语言代码和C++代码--指针、多线程、文件读写、套接字

    C语言代码和C++代码--vs2008从指针到多线程、文件读写、套接字 C: 阶乘 冒泡排序 数值转换 行指针、列指针 形状--打印菱形 指针做冒泡排序 6.5指针函数 6.7用指针显示二维数组 7.1文件操作 7.2文件信息提取 8指针...

    Tornado实现多进程/多线程的HTTP服务详解

    构造函数的参数是一个Handlers列表,通过正则表达式,将请求与Handler对应起来。通过dict将Handler需要的其他对象以参数的方式传递给Handler的initialize方法。 3.初始化一个tornado.httpserver.HTTPServer对象,...

    C++多线程队列

    构造一个队列,并完成入队列和出队列的函数,要求该队列支持多线程 (即一个线程做入队列操作而另一个线程做出队列操作而且两个线程必须同时运行)

    使用Java多线程实现下载多个文件.txt

    其中,构造函数MultiThreadDownloader接收一个URL数组和两个整数数组作为参数,分别表示每个URL的起始字节和结束字节。在download()方法中,根据URL数组创建线程数组,每个线程负责下载一个文件的部分内容。下载部分...

    HTML5新特性 多线程(Worker SharedWorker)

    There is no doubt that JavaScript是没有多线程之说的,... (1)构造函数 new Worker(arg) :参数表示你的线程要执行的代码所在的js文件,例如‘myworker.js’,构造函数当然是返回一个Worker类的实例  (2)worker

    多线程保护应用程序自动加载研究与实践

    可以利用主程序即主进程来构造多个辅助线程,用来监控主进程的运行情况,一旦主进程发生异常,就立刻恢复主进程的原始状态,这样就实现了应用程序无法关闭客户启动时加载自己的应用程序,保证在服务进程中该程序的正常...

    事件驱动多线程网络框架

    这里的Channel并不直接使用而是做基类存在的,更直接的操作在Acceptor和TcpConnection中,其中的 Acceptor 对应了接受连接的socketfd,而TcpConnection则封装了socket的读写操作,在Server的构造函数中会创建一个...

    JAVA多线程并发下的单例模式应用

    单例模式应该是设计模式中比较简单的一个,也是非常常见的,但是在多线程并发的环境下使用却是不那么简单了,今天给大家分享一个我在开发过程中遇到的单例模式的应用。 首先我们先来看一下单例模式的定义: 一个类有...

Global site tag (gtag.js) - Google Analytics