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不剃头的一休哥

时间: 2024-12-25 04:01:36

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

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

Java中的多线程你只要看这一篇就够了 引 如果对什么是线程.什么是进程仍存有疑惑,请先Google之,因为这两个概念不在本文的范围之内. 用多线程只有一个目的,那就是更好的利用cpu的资源,因为所有的多线程代码都可以用单线程来实现.说这个话其实只有一半对,因为反应"多角色"的程序代码,最起码每个角色要给他一个线程吧,否则连实际场景都无法模拟,当然也没法说能用单线程来实现:比如最常见的"生产者,消费者模型". 很多人都对其中的一些概念不够明确,如同步.并发等等,让我

Java中的 多线程编程

Java 中的多线程编程 一.多线程的优缺点 多线程的优点: 1)资源利用率更好2)程序设计在某些情况下更简单3)程序响应更快 多线程的代价: 1)设计更复杂虽然有一些多线程应用程序比单线程的应用程序要简单,但其他的一般都更复杂.在多线程访问共享数据的时候,这部分代码需要特别的注意.线程之间的交互往往非常复杂.不正确的线程同步产生的错误非常难以被发现,并且重现以修复. 2)上下文切换的开销当CPU从执行一个线程切换到执行另外一个线程的时候,它需要先存储当前线程的本地的数据,程序指针等,然后载入另

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

如果对什么是线程.什么是进程仍存有疑惑,请先Google之,因为这两个概念不在本文的范围之内. 用多线程只有一个目的,那就是更好的利用cpu的资源,因为所有的多线程代码都可以用单线程来实现.说这个话其实只有一半对,因为反应“多角色”的程序代码,最起码每个角色要给他一个线程吧,否则连实际场景都无法模拟,当然也没法说能用单线程来实现:比如最常见的“生产者,消费者模型”. 很多人都对其中的一些概念不够明确,如同步.并发等等,让我们先建立一个数据字典,以免产生误会. 多线程:指的是这个程序(一个进程)运

黑马程序员【Java中的多线程】

Java中的多线程 首先,在开篇讲线程之前要说一个问题,我们知道多线程的执行原理是cpu在不同的线程中做着切换操作,而一提到多线程,大家首先想到的肯定是提高系统的运行效率,可是真的是这样的么?我们来借助一位大神博客中的代码就可以看出来有时单线程的运行效率要高于多线程: import threading from time import ctime class MyThread(threading.Thread): def __init__(self, func, args, name): thr

java 中的多线程

java中实现多线程的方式有两种: 1.实现继承Thread 类的类(重写run方法) 2.实现Runnable 接口(重写run方法) 上述两种方式的关系; 看过jdk你会发现 Thread类是实现了 runnable的接口了的   可见,实现Runnable接口相对于继承Thread类来说,有如下显著的优势: (1). 适合多个相同程序代码的线程去处理同一资源的情况,把虚拟CPU(线程)同程序的代码.数据有效分离,较好地体现了面向对象的设计思想. (2). 可以避免由于Java的单继承特性带

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

本文主要从整体上介绍Java中的多线程技术,对于一些重要的基础概念会进行相对详细的介绍,若有叙述不清晰或是不正确的地方,希望大家指出,谢谢大家:) 为什么使用多线程 并发与并行 我们知道,在单核机器上,"多进程"并不是真正的多个进程在同时执行,而是通过CPU时间分片,操作系统快速在进程间切换而模拟出来的多进程.我们通常把这种情况成为并发,也就是多个进程的运行行为是"一并发生"的,但不是同时执行的,因为CPU核数的限制(PC和通用寄存器只有一套,严格来说在同一时刻只能

为什么Java中实现多线程的方式有两种?

在面试的过程中,我们经常问被面试者,为什么Java中实现多线程的方式有两种(一种是直接继承Thread类,一种是实现Runnable接口)?可惜的是,很多面试者都答不出来,甚至从来没有想为什么.,那么真正的原因是什么呢?我们可以用反证法推理一下: 假设Java只提供Thread供大家继承从而实现多线程,考虑下面的一个需求,如果有一个已经继承了某个父类的类,但是这个类又想实现多线程,怎么办?很显然,如果只提供一个可以继承的类,肯定解决不了这个问题.那么,如何解决,毫无疑问,就只能使用接口了.

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

申明: 实习生的肤浅理解,如发现有错误之处,还望大牛们多多指点 废话 其实我写java的后台操作,我每次都会遇到一条语句:List<XXXXX> list = new ArrayList<XXXXX>(); 但是我仅仅只是了解,list这个类是一个可变长用来存储的对象实例的类,我甚至觉得这个List对象可以理解成数组,但是却又与java中咱们正常理解的数组很多的不同,比如说,他的长度可以随着需要自动增长,比如说,实例化一个List类就和咱们声明数组的时候是不一样的! 今天的实习生活

Java中使用多线程、curl及代理IP模拟post提交和get访问

Java中使用多线程.curl及代理IP模拟post提交和get访问 菜鸟,多线程好玩就写着玩,大神可以路过指教,小弟在这受教,谢谢! [java] view plaincopyprint? /** * @组件名:javaDemo * @包名:javaDemo * @文件名:Jenny.java * @创建时间: 2014年8月1日 下午5:53:48 * @版权信息:Copyright ? 2014 eelly Co.Ltd,小姨子版权所有. */ package javaDemo; impo