Java中的多线程操作初探
问题引出:
说是java,其实还是在做android的时候遇到的问题,在android 4.0以后,访问网络必须在新线程中实现,所以才会遇到这个问题。只是为了方面说明问题,才新建一个java项目。在main函数里,用自定义的类创建新对象时,新对象的值是怎么变化的。首先看一下项目的目录

项目中包括两个文件,一个是first.java这个是main函数所在的位置,second.java是自定义类。
step1、
second.java代码
public class second {
int a;
int b;
public second()
{
set();
}
private void set() {
// TODO Auto-generated method stub
a = 1;
b = 2;
}
}
first.java代码
public class first
{
public static void main(String args[])
{
second se = new second();
System.out.println(se.a+"&&"+se.b); }
}
显而易见,输出结果是a=1,b=2;这没什么争议。
step2、现在,我们在second.java,再自定义一个内部类,就叫test吧。代码如下:
public class second {
int a;
int b;
class test
{
int ta;
int tb;
}
test mtest[];
public second()
{
set();
}
private void set() {
// TODO Auto-generated method stub
a = 1;
b = 2;
mtest = new test[2];
mtest[0] = new test();
mtest[1] = new test();
mtest[0].ta=3;
mtest[0].tb=4;
mtest[1].ta=5;
mtest[1].tb=6;
}
}
first.java代码
public class first
{
public static void main(String args[])
{
second se = new second();
System.out.println(se.a+"&&"+se.b);
System.out.println(se.mtest[1].ta+"&&"+se.mtest[1].tb);
}
}
这个结果也很好得出,se.mtest[1].ta = 5,se.mtest[1].tb=6;也没问题。
下面重点来了,上面两步都没有涉及到多线程,现在我们修改一下second.java代码,如下:
public class second {
int a;
int b;
class test
{
int ta;
int tb;
}
test mtest[];
public second()
{
set();
}
private void set() {
// TODO Auto-generated method stub
a = 1;
b = 2;
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
mtest = new test[2];
mtest[0] = new test();
mtest[1] = new test();
mtest[0].ta=3;
mtest[0].tb=4;
mtest[1].ta=5;
mtest[1].tb=6;
}
}).start();
}
}
first.java代码不变
public class first
{
public static void main(String args[])
{
second se = new second();
System.out.println(se.a+"&&"+se.b);
System.out.println(se.mtest[1].ta+"&&"+se.mtest[1].tb);
}
}
这次结果应该是什么呢?如果你说结果不变,那就打错特错了。
口说无凭,结果截图如下:
对,你没有看错,我也没有传错照片,就是抛出异常。那么问题来了,这是为什么呢?
如果要搞清这个问题,就要先清楚电脑的多线程的处理机制。
在计算机组成原理中,我们知道,电脑的多线程并不是真正的平行关系,严格意义上讲,只有一个线程。
举个例子来说,第一个想到的就是绣花(和双面绣差不多),在绣制的时候我们只看一面,但是绣完之后两面都完成了。其实和这个原理一样。
首先,我们只有一根线,用这一根线绣出两面。在正面绣一针之后,穿到反面再绣一针,就这样依次循环。
电脑的多线程处理也是如此,假设有两个线程A,B,A执行一会,B再执行一会。当然,电脑的线程处理并不是这么简单,
如果要再细说的话,电脑会给每个线程指定优先级,优先级决定了线程的执行顺序和分配给它的电脑资源。
总之,严格的说多线程并不是平行关系,而是根据某种规则轮流执行,只是这中间的时间单位很短,用户基本无法察觉。
所以,代码抛出异常的原因是:当主线程执行到最后的时候,我们新开的线程却没有执行完。以至于抛出空指针。
怎么解决呢?那就主线程休息一会等待新线程执行结束,调用sleep函数即可。
所以,修改后的java代码如下:
public class first
{
public static void main(String args[])
{
second se = new second();
System.out.println(se.a+"&&"+se.b);
try {
Thread.sleep(5*1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(se.mtest[1].ta+"&&"+se.mtest[1].tb);
}
}
我们让主线程休息5s。下面是执行结果:

结果就是这样。
附:
1、代码有问题不要找我,是他自己长歪的
2、欢迎批评之
3、转载就注明出处by不剃头的一休哥
Java中的多线程操作初探的更多相关文章
- Java 中传统多线程
目录 Java 中传统多线程 线程初识 线程的概念 实现线程 线程的生命周期 常用API 线程同步 多线程共享数据的问题 线程同步及实现机制 线程间通讯 线程间通讯模型 线程中通讯的实现 @(目录) ...
- Java中的 多线程编程
Java 中的多线程编程 一.多线程的优缺点 多线程的优点: 1)资源利用率更好2)程序设计在某些情况下更简单3)程序响应更快 多线程的代价: 1)设计更复杂虽然有一些多线程应用程序比单线程的应用程序 ...
- java中的多线程 // 基础
java 中的多线程 简介 进程 : 指正在运行的程序,并具有一定的独立能力,即 当硬盘中的程序进入到内存中运行时,就变成了一个进程 线程 : 是进程中的一个执行单元,负责当前程序的执行.线程就是CP ...
- Java中的多线程=你只要看这一篇就够了
如果对什么是线程.什么是进程仍存有疑惑,请先Google之,因为这两个概念不在本文的范围之内. 用多线程只有一个目的,那就是更好的利用cpu的资源,因为所有的多线程代码都可以用单线程来实现.说这个话其 ...
- Android学习记录(5)—在java中学习多线程下载之断点续传②
在上一节中我们学习了在java中学习多线程下载的基本原理和基本用法,我们并没有讲多线程的断点续传,那么这一节我们就接着上一节来讲断点续传,断点续传的重要性不言而喻,可以不用重复下载,也可以节省时间,实 ...
- Java并发--Java中的CAS操作和实现原理
版权声明:本文为博主原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/CringKong/article/deta ...
- Java中的多线程技术全面详解
本文主要从整体上介绍Java中的多线程技术,对于一些重要的基础概念会进行相对详细的介绍,若有叙述不清晰或是不正确的地方,希望大家指出,谢谢大家:) 为什么使用多线程 并发与并行 我们知道,在单核机器上 ...
- JAVA中的时间操作
java中的时间操作不外乎这四种情况: 1.获取当前时间 2.获取某个时间的某种格式 3.设置时间 4.时间的运算 好,下面就针对这四种情况,一个一个搞定. 一.获取当前时间 有两种方式可以获得,第一 ...
- java中的集合操作类(未完待续)
申明: 实习生的肤浅理解,如发现有错误之处.还望大牛们多多指点 废话 事实上我写java的后台操作,我每次都会遇到一条语句:List<XXXXX> list = new ArrayList ...
随机推荐
- Asp.Net判断字符是否为汉字的方法大全
判断一个字符是不是汉字通常有三种方法: 第一种用 ASCII 码判断,缺点:把全角逗号“,”当汉字处理 第二种用汉字的 UNICODE 编码范围判 断, 第三种用正则表达式判断 1.用ASCII码判断 ...
- c#Winform程序,让pictureBox显示图像(包含GIF),并且不被占用,能即时删除图片。
最近在做一个图片浏览的工具, 需要在PictureBox中显示图像文件, 包括gif播放. 且不能被程序独占, 就算winform的程序正在显示这张图, 也能在资源管理器里delete它. 看了看网 ...
- python练习程序(c100经典例14)
题目: 将一个正整数分解质因数.例如:输入90,打印出90=2*3*3*5. def foo(n): while 1: for i in range(2,n+1): if n%i==0: print ...
- PHP实现站点pv,uv统计(三)
数据分析脚本如下: //error_reporting(0);date_default_timezone_set("PRC");$environment = get_cfg_var ...
- python 传入参数返回的时候好像有些时候会出现莫名其妙的循环
def handle_field(name, s_len, s): #some code #return s would error but return not.... #return s for ...
- Informatica9.6.1在Linux Red Hat 5.8上安装遇到的有关问题整理_1
1. 产品安装过程中提示无法创建Domain([ICMD_10033] Command [defineDomain] failed with error [[INFASETUP_10002]) 1) ...
- YII Framework学习教程-YII的国际化
一个web应用,发布到互联网,就是面向全球用户.用户在世界的各个角落都可以访问到你的web应用,当然要看你的网站和不和谐,不和谐的web应用在和谐社会是不让你访问的. YII提供了国际化的支持,可以让 ...
- c# 读取IntPtr 中的数据 z
c++的写法是这样的: LRESULT CPictureQueryDlg::OnQueryPicNty(WPARAM wp, LPARAM lp) { EnableWindow(TRUE); BYTE ...
- 计算器显示e-005什么意思
计算器显示e-005什么意思 1e-005是科学表达式,即 =1e-5 =0.00001e+005就是乘以10的5次方 就是-1.4989*10^5 这是科学计数法(也叫指数计数法) 这是科学计数 ...
- Visual Studio 2005 移植 - WINVER,warning C4996, error LINK1104
Visual Studio 2005 移植 - WINVER,warning C4996, error LINK1104 一.WINVER Compile result: WINVER not d ...