问题引出:

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

项目中包括两个文件,一个是first.java这个是main函数所在的位置,second.java是自定义类。

step1、

second.java代码

  1. public class second {
  2. int a;
  3. int b;
  4.  
  5. public second()
  6. {
  7. set();
  8. }
  9. private void set() {
  10. // TODO Auto-generated method stub
  11. a = 1;
  12. b = 2;
  13.  
  14. }
  15. }

first.java代码

  1. public class first
  2. {
  3. public static void main(String args[])
  4. {
  5. second se = new second();
  6. System.out.println(se.a+"&&"+se.b);
  7.  
  8. }
  9. }

显而易见,输出结果是a=1,b=2;这没什么争议。

step2、现在,我们在second.java,再自定义一个内部类,就叫test吧。代码如下:

  1. public class second {
  2. int a;
  3. int b;
  4. class test
  5. {
  6. int ta;
  7. int tb;
  8. }
  9. test mtest[];
  10. public second()
  11. {
  12. set();
  13. }
  14. private void set() {
  15. // TODO Auto-generated method stub
  16. a = 1;
  17. b = 2;
  18.  
  19. mtest = new test[2];
  20. mtest[0] = new test();
  21. mtest[1] = new test();
  22. mtest[0].ta=3;
  23. mtest[0].tb=4;
  24. mtest[1].ta=5;
  25. mtest[1].tb=6;
  26. }
  27. }

first.java代码

  1. public class first
  2. {
  3. public static void main(String args[])
  4. {
  5. second se = new second();
  6. System.out.println(se.a+"&&"+se.b);
  7. System.out.println(se.mtest[1].ta+"&&"+se.mtest[1].tb);
  8. }
  9. }

这个结果也很好得出,se.mtest[1].ta = 5,se.mtest[1].tb=6;也没问题。

下面重点来了,上面两步都没有涉及到多线程,现在我们修改一下second.java代码,如下:

  1. public class second {
  2. int a;
  3. int b;
  4. class test
  5. {
  6. int ta;
  7. int tb;
  8. }
  9. test mtest[];
  10. public second()
  11. {
  12. set();
  13. }
  14. private void set() {
  15. // TODO Auto-generated method stub
  16. a = 1;
  17. b = 2;
  18.  
  19. new Thread(new Runnable() {
  20. @Override
  21. public void run() {
  22. // TODO Auto-generated method stub
  23. mtest = new test[2];
  24. mtest[0] = new test();
  25. mtest[1] = new test();
  26. mtest[0].ta=3;
  27. mtest[0].tb=4;
  28. mtest[1].ta=5;
  29. mtest[1].tb=6;
  30. }
  31. }).start();
  32. }
  33. }

first.java代码不变

  1. public class first
  2. {
  3. public static void main(String args[])
  4. {
  5. second se = new second();
  6. System.out.println(se.a+"&&"+se.b);
  7. System.out.println(se.mtest[1].ta+"&&"+se.mtest[1].tb);
  8. }
  9. }

这次结果应该是什么呢?如果你说结果不变,那就打错特错了。

口说无凭,结果截图如下:

  

对,你没有看错,我也没有传错照片,就是抛出异常。那么问题来了,这是为什么呢?

如果要搞清这个问题,就要先清楚电脑的多线程的处理机制。

在计算机组成原理中,我们知道,电脑的多线程并不是真正的平行关系,严格意义上讲,只有一个线程。

举个例子来说,第一个想到的就是绣花(和双面绣差不多),在绣制的时候我们只看一面,但是绣完之后两面都完成了。其实和这个原理一样。

首先,我们只有一根线,用这一根线绣出两面。在正面绣一针之后,穿到反面再绣一针,就这样依次循环。

电脑的多线程处理也是如此,假设有两个线程A,B,A执行一会,B再执行一会。当然,电脑的线程处理并不是这么简单,

如果要再细说的话,电脑会给每个线程指定优先级,优先级决定了线程的执行顺序和分配给它的电脑资源。

总之,严格的说多线程并不是平行关系,而是根据某种规则轮流执行,只是这中间的时间单位很短,用户基本无法察觉。

所以,代码抛出异常的原因是:当主线程执行到最后的时候,我们新开的线程却没有执行完。以至于抛出空指针。

怎么解决呢?那就主线程休息一会等待新线程执行结束,调用sleep函数即可。

所以,修改后的java代码如下:

  1. public class first
  2. {
  3. public static void main(String args[])
  4. {
  5. second se = new second();
  6. System.out.println(se.a+"&&"+se.b);
  7. try {
  8. Thread.sleep(5*1000);
  9. } catch (InterruptedException e) {
  10. // TODO Auto-generated catch block
  11. e.printStackTrace();
  12. }
  13. System.out.println(se.mtest[1].ta+"&&"+se.mtest[1].tb);
  14. }
  15. }

我们让主线程休息5s。下面是执行结果:

结果就是这样。

附:

1、代码有问题不要找我,是他自己长歪的

2、欢迎批评之

3、转载就注明出处by不剃头的一休哥

Java中的多线程操作初探的更多相关文章

  1. Java 中传统多线程

    目录 Java 中传统多线程 线程初识 线程的概念 实现线程 线程的生命周期 常用API 线程同步 多线程共享数据的问题 线程同步及实现机制 线程间通讯 线程间通讯模型 线程中通讯的实现 @(目录) ...

  2. Java中的 多线程编程

    Java 中的多线程编程 一.多线程的优缺点 多线程的优点: 1)资源利用率更好2)程序设计在某些情况下更简单3)程序响应更快 多线程的代价: 1)设计更复杂虽然有一些多线程应用程序比单线程的应用程序 ...

  3. java中的多线程 // 基础

    java 中的多线程 简介 进程 : 指正在运行的程序,并具有一定的独立能力,即 当硬盘中的程序进入到内存中运行时,就变成了一个进程 线程 : 是进程中的一个执行单元,负责当前程序的执行.线程就是CP ...

  4. Java中的多线程=你只要看这一篇就够了

    如果对什么是线程.什么是进程仍存有疑惑,请先Google之,因为这两个概念不在本文的范围之内. 用多线程只有一个目的,那就是更好的利用cpu的资源,因为所有的多线程代码都可以用单线程来实现.说这个话其 ...

  5. Android学习记录(5)—在java中学习多线程下载之断点续传②

    在上一节中我们学习了在java中学习多线程下载的基本原理和基本用法,我们并没有讲多线程的断点续传,那么这一节我们就接着上一节来讲断点续传,断点续传的重要性不言而喻,可以不用重复下载,也可以节省时间,实 ...

  6. Java并发--Java中的CAS操作和实现原理

    版权声明:本文为博主原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/CringKong/article/deta ...

  7. Java中的多线程技术全面详解

    本文主要从整体上介绍Java中的多线程技术,对于一些重要的基础概念会进行相对详细的介绍,若有叙述不清晰或是不正确的地方,希望大家指出,谢谢大家:) 为什么使用多线程 并发与并行 我们知道,在单核机器上 ...

  8. JAVA中的时间操作

    java中的时间操作不外乎这四种情况: 1.获取当前时间 2.获取某个时间的某种格式 3.设置时间 4.时间的运算 好,下面就针对这四种情况,一个一个搞定. 一.获取当前时间 有两种方式可以获得,第一 ...

  9. java中的集合操作类(未完待续)

    申明: 实习生的肤浅理解,如发现有错误之处.还望大牛们多多指点 废话 事实上我写java的后台操作,我每次都会遇到一条语句:List<XXXXX> list = new ArrayList ...

随机推荐

  1. 事件类型: 错误 事件来源: Service Control Manager 事件种类: 无 事件 ID: 7000

    在控制面板\管理工具\服务里找dns Client 服务,把他启动了

  2. VBScript - CUD registry key and value

    http://msdn.microsoft.com/en-us/library/aa384906(v=vs.85).aspx HKEY_LOCAL_MACHINE = &H80000002 s ...

  3. 移动金融APP分析

    最近研究了移动互联网金融APP的情况,分享给大家. 这是官方关于互联网金融的范围,包括支付.借贷.众筹.基金.保险和信托. 典型的APP 绑卡的流程普遍采用的四要素鉴权:姓名,身份证,卡号以及银行预留 ...

  4. Spring无配置使用properties文件

    利用@PropertySource注解加载 @Configuration @ComponentScan(basePackages="*") @PropertySource({&qu ...

  5. php时区测试

    php里面关于时间的函数有date,time,strtotime,gmdate等,里面只要和时间字符串相关的基本都收到时区的影响,所以时间戳才是唯一稳定时间记录,因为标准都是统一的.这里联想到数据库的 ...

  6. 【转】使用Python的IDE:Eclipse+PyDev

    原文网址:http://www.crifan.com/try_with_python_ide_eclipse_pydev/ 之前已经介绍过了一些基本知识: [整理][多图详解]如何在Windows下开 ...

  7. PHP的cURL库:抓取网页,POST数据及其他,HTTP认证 抓取数据

    From : http://developer.51cto.com/art/200904/121739.htm 下面是一个小例程: ﹤?php// 初始化一个 cURL 对象$curl = curl_ ...

  8. 使用C#代码发起K2 Blackpearl流程

    转:http://www.cnblogs.com/dannyli/archive/2011/08/02/2125285.html 使用C#代码,发起一个K2的流程,其形式和链接SQL Server数据 ...

  9. 18个jQuery Mobile开发贴士和教程

    jQuery Mobile 是 jQuery 在手机上和平板设备上的版本.jQuery Mobile 不仅会给主流移动平台带来jQuery核心库,而且会发布一个完整统一的jQuery移动UI框架.支持 ...

  10. Worm

    Description 自从见识了平安夜苹果的涨价后,Lele就在他家门口水平种了一排苹果树,共有N棵. 突然Lele发现在左起第P棵树上(从1开始计数)有一条毛毛虫.为了看到毛毛虫变蝴蝶的过程,Le ...