`

多线程构造函数

 
阅读更多
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
 *///:~

 

分享到:
评论

相关推荐

    关于C#多线程的函数示例

    创建一个不带参数的线程函数,我们可以使用`Thread`类的构造函数,如下所示: ```csharp using System.Threading; public class MultiThreadExample { public void RunWithoutParameter() { // 创建一个新的...

    Java多线程开发(构造函数的使用)

    本文主要总结了Java多线程开发中线程创建时多用到的创建方式(不同的构造函数)以及线程组相关的基础知识

    Java多线程机制(讲述java里面与多线程有关的函数)

    另一种创建线程的方法是实现Runnable接口,创建一个实现了Runnable接口的类,然后在Thread构造函数中传入该类的实例。线程启动后,会调用Runnable接口的run()方法。 9.4 线程的常用方法: - `start()`: 使线程从...

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

    本文将讲述一个关于在类的构造函数和析构使用临界区函数导致的多线程死锁的经验之谈。 首先,让我们先了解什么是临界区函数。临界区函数是一种用于保护共享资源的机制,当多个线程访问同一个共享资源时,临界区函数...

    C#中静态构造函数的几点说明介绍

    静态构造函数的执行顺序可能会引起一些有趣的现象,比如在多线程环境中,由于调用的不确定性,可能导致预期之外的行为。以下是一些示例说明这一点: 在Demo1中,尽管`B`类覆盖了`strText`,但在`Main`方法中直接...

    大漠多线程模板_大漠_大漠多线程_

    开发者可以通过传递一个委托(即方法引用)到`Thread`构造函数来启动新的线程。大漠的模板可能提供了一种更简洁的方式,允许开发者通过一个友好的接口创建线程。 2. **线程同步**:在多线程环境中,防止数据竞争和...

    拷贝构造函数和赋值运算符的区别.pdf

    例如,如果一个类对象包含指向动态分配内存的指针,如`CExample`类所示,那么默认的拷贝构造函数只会复制指针,而不是指针指向的数据,导致两个对象共享同一内存,这在多线程或对象生命周期管理中可能引发错误。...

    kei开发ARM实现构造函数测完整工程试.zip

    9. **多线程环境下的构造**:在并发环境中,测试构造函数的线程安全性,避免数据竞争和同步问题。 通过这个测试工程,开发者可以了解在ARM平台上构造函数的具体实现细节,找出可能存在的问题,优化代码以适应特定...

    12.1 Qt5多线程:多线程及简单实例

    在编程领域,尤其是在开发高效、响应迅速的应用程序时,多线程技术扮演着至关重要的角色。Qt5框架提供了一种方便的方式来实现多线程,它允许开发者在不同的线程中执行任务,从而避免主线程(GUI线程)因处理耗时操作...

    dotnet 谨慎在静态构造函数里使用锁.rar

    在多线程环境中,如果在静态构造函数中使用锁,可能会导致死锁或性能下降。原因在于,静态构造函数已经隐含了线程安全性,添加锁可能会与.NET运行时的内部同步机制冲突,增加不必要的复杂性。此外,由于静态构造函数...

    不同编译环境下的拷贝构造函数解决方案.zip_C++_NQW

    Code::Blocks则是一个轻量级的IDE,它可能对编译器的默认行为更加保守,但在某些情况下,用户可能需要显式地定义拷贝构造函数来确保正确的行为,尤其是当涉及到多线程、智能指针或者资源管理类时。 解决不同编译...

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

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

    java 多线程操作数据库

    示例中,`ThreadUseExtends`类的构造函数接收BLOB和CLOB文件名作为参数,并在运行时读取这些文件的内容,将其转换为字节数组或字符串,然后插入到数据库相应的字段中。 5. **并发控制与事务管理**:在多线程环境下...

    多线程的处理

    1. 创建线程对象:这可能是通过调用特定语言提供的函数或构造函数完成的。 2. 定义线程函数:这是新线程将要执行的代码。 3. 启动线程:启动线程使其开始执行。 在多线程编程中,同步和互斥是两个核心概念。同步...

    java多线程的讲解和实战

    - 实现`Runnable`接口:创建一个新的类,实现`Runnable`接口,实现`run()`方法,然后将这个类的实例传给`Thread`类的构造函数创建线程。 3. **线程同步与通信**: - 同步机制:为了防止多个线程访问同一资源时...

    多线程操作_paintawe_多线程写入例程_

    线程的创建通常包括定义一个函数(线程函数),该函数将在线程运行时被调用,并通过`std::thread`类的构造函数来启动新线程。 "多线程.exe"文件可能是编译后的可执行程序,用户可以直接运行以观察多线程写入的效果...

    dotnet C# 反射扫描程序集所有类型会不会触发类型静态构造函数.rar

    4. **潜在的陷阱**:需要注意的是,静态构造函数的执行顺序可能难以预测,特别是在多线程环境中。如果多个线程同时访问同一类型,可能会导致多个线程尝试执行静态构造函数,这可能会引发错误。因此,设计静态构造...

    多线程例子 演示多线程使用

    首先,你需要定义一个可调用对象(如函数、成员函数或Lambda表达式),然后传递给`std::thread`的构造函数。例如: ```cpp #include void my_function() { // 线程执行的代码 } int main() { std::thread my_...

    winform 多线程处理数据

    创建一个新的线程需要定义一个方法(线程入口点),然后在线程构造函数中传入该方法的委托。 3. **BackgroundWorker组件** 更常用且推荐的方式是使用`BackgroundWorker`组件,它提供了异步执行任务的能力,并且...

    现代多线程 JAVA和c++多线程实现 测试和调试

    与JAVA不同,C++中的线程对象并不直接执行任务,而是将可调用对象(如函数、函数指针或lambda表达式)作为参数传递给构造函数。线程同步则通过`mutex`(互斥锁)、`condition_variable`(条件变量)、`future`和`...

Global site tag (gtag.js) - Google Analytics