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 MVC 4 WebAPI. Support Areas in HttpControllerSelector
This article was written for ASP.NET MVC 4 RC (Release Candidate). If you are still using Beta versi ...
- Android init.rc文件格式解析
/***************************************************************************** * Android init.rc文件格式 ...
- postgresql - mac 启动 关闭 postgresql
/Library/PostgreSQL/9.3/bin/pg_ctl -D /Library/PostgreSQL/9.3/data stop /Library/PostgreSQL/9.3/bin/ ...
- (转) Python Generators(生成器)——yield关键字
http://blog.csdn.net/scelong/article/details/6969276 生成器是这样一个函数,它记住上一次返回时在函数体中的位置.对生成器函数的第二次(或第 n 次) ...
- marginCollapse之兄弟关系的DIV
废话不说,直接上图 基本代码如下: 效果图如下: 给两个div分别加marginBottom和marginTop看一下效果 实际效果如下: 我们可以看出两个div之间的距离并不是50+50,而是只显示 ...
- XAMPP 的安装配置
--转载时请保留下面,以供大家加我MSN,增强交流,共同学习.--姜庭华 msn: jaimejth@live.cn--博客:http://blog.csdn.net/jaimejth 软件下载在以 ...
- DOMContentLoaded事件
今天查看百度空间源代码,发现多了个util.js文件,打开看看.里面里面定义了addDOMLoadEvent.这是干什么用的? 仔细查看代码,发现在Mozilla添加了DOMContentLoaded ...
- 让层遮挡select(ie6下的问题)
虽然现在很多比较大的网站已经不考虑ie6了,不过这些方法,或者其中原理还是值得记录下来的.所以整理的时候,把这篇文章留下了. <script language="javascript& ...
- ubuntu 切换工作区域
在Ubuntu 13.04中,默认是不激活多桌面工作空间的,所以在之前的版本可以在启动器看到的那个像“田”字的“工作区切换器”图标没有了,始终只有一个桌面了.要激活工作空间,在system setti ...
- pdm 中怎么修改表的Name值时使Code值不变
修改方法:PowerDesign中的选项菜单里修改,在[Tool]-->[General Options]->[Dialog]->[Operating modes]->[Nam ...