`

线程对对象的操作不解

阅读更多
package com.yuan;

import java.io.Serializable;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class TestThreadPool {
	private static int produceTaskSleepTime = 3000;
	private static int consumeTaskSleepTime = 2000;
	private static int produceTaskMaxNumber = 1;

	public static void main(String[] args) {
		// 构造一个线程池
		ThreadPoolExecutor threadPool = new ThreadPoolExecutor(2,4, 3,
				TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(3),
				new ThreadPoolExecutor.DiscardOldestPolicy());
		for (int i = 1; i <= produceTaskMaxNumber; i++) {
			try {
				// 产生一个任务,并将其加入到线程池
				String task = "task@ " + i;
				User u  = new User();
				u.setId(1);
				u.setName("yqf");
				System.out.println("put " + task);
				ThreadPoolTask t =	new ThreadPoolTask(u);
				threadPool.execute(t);
				// 便于观察,等待一段时间
				Thread.sleep(produceTaskSleepTime);
				System.out.println("MAIN TASK:"+ u.getName());
				System.out.println(" t user: " +  t.getUser().getName());
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	/**
	 * 线程池执行的任务
	 * @author hdpan
	 */
	public static class ThreadPoolTask implements Runnable, Serializable {
		private static final long serialVersionUID = 0;
		// 保存任务所需要的数据
		private User threadPoolTaskData;
		ThreadPoolTask(User tasks) {
			this.threadPoolTaskData = tasks;
		}
		public void run() {
			// 处理一个任务,这里的处理方式太简单了,仅仅是一个打印语句
			System.out.println("start .." + threadPoolTaskData);
			/*try {
				// //便于观察,等待一段时间
				Thread.sleep(consumeTaskSleepTime);
			} catch (Exception e) {
				e.printStackTrace();
			}*/
			System.out.println("ThreadPoolTask task:" + threadPoolTaskData);
			threadPoolTaskData = null;
			//threadPoolTaskData.setName("3333");
		}
		public User getUser(){
			return threadPoolTaskData;
		}
	}

}

 以上代码是主线程构造一个User对象,将user对象传入线程,线程里面对user进行了=null操作。然后回主线程,发现去取System.out.println("MAIN TASK:"+ u.getName());
的时候,还是可以取到,但是调用System.out.println(" t user: " +  t.getUser().getName());
确实空指针。

 

而且如果你在子线程里面对user进行了修改名字操作,System.out.println("MAIN TASK:"+ u.getName());
也是可以找到子线程操作后的user的。

 

不明白为何会这样??

分享到:
评论

相关推荐

    易语言线程互斥对象解决

    线程互斥对象允许我们限制对共享资源的访问,防止多个线程同时访问同一资源,从而避免数据竞争和不一致状态。 1. **线程互斥对象(Mutex)**: 线程互斥对象是一种同步机制,当一个线程获得了Mutex的所有权后,...

    多线程事件对象通讯

    "多线程事件对象通讯"的示例,如`vc技术内幕11章例子`所示,深入探讨了如何在Visual C++(VC)环境下利用事件对象进行线程间的交互。 事件对象有三种状态:信号状态(Signaled State)和非信号状态(Non-Signaled ...

    C++11/14 线程调用类对象和线程传参的方法

    线程调用类对象 在前面的示例中,我们为线程任务使用了通常的函数。实际上,我们可以使用任何可调用对象或者lambda函数,如下调用类对象的例子: #include #include class MyFunctor { public: void operator()...

    C#线程进程操作

    例如,使用`lock`关键字可以确保在同一时刻只有一个线程能够访问特定对象: ```csharp lock (myObject) { // 临界区代码,只允许一个线程执行 } ``` **线程池**是C#中管理线程的一种高效方式,通过`ThreadPool`类...

    java 多线程操作数据库

    ### Java多线程操作数据库:深入解析与应用 在当今高度并发的应用环境中,Java多线程技术被广泛应用于处理数据库操作,以提升系统的响应速度和处理能力。本文将基于一个具体的Java多线程操作数据库的应用程序,深入...

    c++ 面向对象多线程编程

    在C++编程中,面向对象和多线程是两个重要的概念,它们对于开发高效、并发的软件至关重要。本文将深入探讨这两个主题,并结合C++语言特性进行详细解释。 首先,让我们了解一下面向对象编程(Object-Oriented ...

    delphiXE多线程同步对象及异步执行.zip

    Delphi提供了各种同步对象,如TCriticalSection、TSemaphore、TMutex等,来实现线程同步。例如,TCriticalSection用于在多线程中保护临界区,确保同一时间只有一个线程能进入该区域。使用TryEnterCriticalSection和...

    C++ 创建线程互斥对象

    6. **事件对象**:在某些情况下,可能还需要使用事件对象(如`std::condition_variable`)来同步线程间的操作。例如,当线程需要等待某个条件满足时,可以使用`wait()`函数释放互斥量并挂起线程,而其他线程可以使用...

    多线程面向对象电梯设计

    在本文中,我们将深入探讨如何使用面向对象编程和多线程技术来设计一个电梯系统,以实现高效且并发的操作。这个项目是基于VC6.0开发环境,它是一款经典的Microsoft Visual C++集成开发环境,虽然现在已经有些过时,...

    线程同步对象方法

    线程同步是多线程编程中的关键概念,其目的是确保在多线程环境中,对共享资源的访问能够按照预定的顺序或协调方式进行,避免数据不一致性和竞态条件。线程同步是解决并发问题的一种机制,它使得在特定时刻只有一个...

    VC 线程 创建 操作 同步 终止 UI线程等各种线程例子

    创建新的线程时需要注意,对UI的操作必须在UI线程中进行。 7. **Worker线程**: - Worker线程是负责执行后台任务的线程,不直接与用户交互。它们通常用于执行计算密集型任务或长时间运行的任务,以免阻塞UI线程。 ...

    java多线程的条件对象和锁对象demo

    本示例"java多线程的条件对象和锁对象demo"着重探讨了如何利用锁对象和条件对象来精细控制线程的执行流程。 首先,我们需要了解Java中的锁对象。Java提供了多种类型的锁,其中最基础的是`synchronized`关键字,它...

    多线程同时操作全局变量的出错演示

    `CMutex`的工作原理类似于互斥锁,通过获取和释放互斥对象的拥有权来控制对资源的访问。当一个线程获得了`CMutex`,其他尝试获取的线程将会被阻塞,直到拥有者释放。 在“ThreadProblem1”的代码示例中,可能包含了...

    面向对象的多线程编程

    在C++11标准中引入了对线程的支持,并且在后续版本中不断改进。通过使用`&lt;thread&gt;`库,开发者可以轻松地创建和管理线程,实现更高效的应用程序。 ##### 线程基础 - **线程对象**:`std::thread`是C++标准库中用于...

    vc++ multithread多线程教程---线程通信--利用事件对象,线程同步--使用信号量,线程同步--使用互斥量,线程同步--使用临界区

    本教程将深入探讨四种常见的线程同步机制:事件对象、信号量、互斥量以及临界区,帮助开发者理解和掌握如何在VC++中安全地实现多线程通信。 一、事件对象 事件对象是Windows API中用于线程间通信的一种同步机制。它...

    STA客户跨线程调用STA对象

    这种数据结构允许多个线程同时读取,而对写入操作则采用锁定或其他同步机制,保证数据的一致性。 综上所述,"STA客户跨线程调用STA对象"涉及到COM编程中的线程模型、消息循环、跨线程通信机制以及同步原语的使用。...

    C++面向对象多线程编程

    《C++面向对象多线程编程》共分13章,全面讲解构建多线程架构与增量多线程编程技术。第1章介绍了用于构建面向对象程序的不同类型C++组件,以及如何使用这些组件来构建多线程架构。第2、3、4章简要介绍进程、线程、多...

    操作系统实验(三)线程的互斥

    通过对“线程的互斥”这一实验的学习,我们不仅掌握了如何在Windows系统环境中创建和管理线程,更重要的是学会了使用临界区对象或互斥对象来避免竞态条件,确保多线程环境下的数据一致性。这对于软件开发特别是并发...

    操作系统实验报告——线程与进程同步

    该实验旨在帮助学生掌握操作系统提供的同步机制,并深化对经典同步问题的理解。 实验内容集中在Linux下的多线程同步机制上,具体通过修改生产者-消费者问题的示例程序来实现。在这个问题中,多个生产者线程生成数据...

Global site tag (gtag.js) - Google Analytics