??xml version="1.0" encoding="utf-8" standalone="yes"?> 如同E序和进E的区别Q要掌握多线E编E,W一要弄清的问题是:U程对象和线E的区别?/p>
U程对象是可以生线E的对象。比如在javaq_中Thread对象QRunnable对象。线E,是指正在执行的一个指点o序列。在javaq_上是指从一个线E对象的start()开始,q行runҎ体中的那一D늛对独立的q程?/p>
鉴于作者的水^Q无法用更确切的词汇来描q它们的定义。但q两个有本质区别的概念请初学者细l体会,随着介绍的深入和例程分析的增加,׃慢慢明白它们所代表的真实含义?/p>
天下难事必始于易Q天下大事必始于l?/p>
让我们先从最单的"单线E?来入手:(1)带引可明只是相对而言的单U程Q?2)Zjava?/p>
如果我们成功~译了该java文gQ然后在命o行上敲入Q?/p>
java BeginClass 现在发生了什么呢Q每一个javaE序员,从他开始学习java的第一分钟里都会接触到q个?/p>
题,但是Q你知道它到底发生发什么?
JVMq程被启动,在同一个JVMq程中,有且只有一个进E,是它自己。然后在q个JVM环境中,所有程序的q行都是以线E来q行。JVM最先会产生
一个主U程Q由它来q行指定E序的入口点。在q个E序中,是ȝE从mainҎ开始运行。当mainҎl束后,ȝE运行完成。JVMq程也随之退
出? 我们看到的是一个主U程在运行mainҎQ这L只有一个线E执行程序逻辑的流E我们称 之ؓ单线E?/strong>。这是JVM提供l我们的单线E环境,事实上,JVM底层q至有垃圾回收q样的后台线E以及其它非javaU程Q但q些U程Ҏ们而言不可讉KQ我们只认ؓ它是单线E的?/p>
ȝE是JVM自己启动的,在这里它不是从线E对象生的。在q个U程中,它运行了mainҎq个指o序列。理解它Q但它没有更多可以研I的内容?/p>
[接触多线E] 执行q个E序QmainҎW一行生了一个线E对象,但ƈ没有U程启动?/p>
mainҎW二行生了一个线E对象,q启动了一个线E?/p>
mainҎW三行,产生q启动一个线E后Q主U程自己也l执行其它语句?/p>
我们先不研究Thread对象的具体内容,E微来回想一下上面的两个概念Q?strong>U程对象 在JAVA中,要开始一个线E,有两U方式。一是直接调用Thread实例的start()ҎQ二?br />
Runable实例传给一个Thread实例然后调用它的start()Ҏ?/p>
在前面已l说q,U程对象和线E是两个完全不同的概c这里我们再ơ深入一下,生成一个线E的实例Qƈ不代表启动了U程。而启动线E是说在某个U程对象上启动了该实例对应的U程Q当该线E结束后Qƈ不会qx失?/p>
对于从很多书c上可以看到的基知识我就不用多说了。既然是基础知识Q我也着重于从普通文档上M到的内容。所以本节我重点要说的是两种U程对象产生U程方式的区别?/p>
如果我们生成MyThread的一个实例,然后调用它的start()ҎQ那么就产生了这个实例对应的U程Q?/p>
不用_最l会打印??9Q现在我们稍微玩一点花P 也不用说Q在基础(一Q?/a>中我们知道由于单CPU的原因,一般会先打?01Q然后打??9。不q我们可以控制线E让它按我们的意思来q行Q?/p>
好了Q我们终于看刎ͼmt实例对应的线E?假如我有时说mtU程请你不要怪我Q不q我量不这么说)。在q行完成后,ȝE才打印101。因?
我们让当前线E?q里是主U程){待mtU程的运行结束?在线E对象a上调用join()ҎQ就是让当前正在执行的线E等待线E对象a对应的线E运?
完成后才l箋q行? 请大家一定要深刻理解q熟记这句话Q而我q里引出q个知识点的目的是ؓ了让你l看下面的例子: 当线E对象mtq行完成后,我们让主U程休息一下,然后我们再次在这个线E对象上启动U程。结果我们看刎ͼ Exception in thread "main" java.lang.IllegalThreadStateException 也就是这U线E对象一时运行一ơ完成后Q它再也不能运行第二次了。我们可以看一下它有具体实? 一个Thread的实例一旦调用start()ҎQ这个实例的started标记标CؓtrueQ事实中不管q个U程后来有没有执行到底,只要调用了一ơstart()再也没有机会运行了Q这意味着Q?/p>
那么如果要在一个实例上产生多个U程(也就是我们常说的U程?Q我们应该如何做呢?q就是Runnable接口l我们带来的伟大的功能?/p>
当然q个l果和mt.start()没有什么区别。但如果我们把一个Runnable实例lThread对象多次包装Q我们就可以看到它们实际是在同一实例上启动线E: x是实例对象,但结果是x被加C999Q说明这10个线E是在同一个r对象上运行的。请大家注意Q因个例子是在单CPU上运行的Q所以没
有对多个U程同时操作共同的对象进行同步。这里是Z说明的方便而简化了同步Q而真正的环境中你无法预知E序会在什么环境下q行Q所以一定要考虑同步?/p>
到这里我们做一个完整的例子来说明线E生的方式不同而生成的U程的区别: 上面10个线E对象生的10个线E运行时打印?0?。下?0个线E对象生的10个线E运行时打印??0。我们把下面?0个线E称?strong>同一实例(Runnable实例)的多个线E?/strong>?/p>
[W一需要弄清的问题]
class BeginClass{
public static void main(String[] args){
for(int i=0;i<100;i++)
System.out.println("Hello,World!");
}
}
class MyThread extends Thread{
public void run(){
System.out.println("Thread say:Hello,World!");
}
}
public class MoreThreads{
public static void main(String[] args){
new MyThread();
new MyThread().start();
System.out.println("Main say:Hello,World");
}
}
现在我们来开始考察JAVA中线E对象?
class MyThread extends Thread{
public int x = 0;
public void run(){
for(int i=0;i<100;i++){
try{
Thread.sleep(10);
}catch(Exception e){}
System.out.println(x++);
}
}
}
public class Test {
public static void main(String[] args) throws Exception{
MyThread mt = new MyThread();
mt.start();
}
}
public class Test {
public static void main(String[] args) throws Exception{
MyThread mt = new MyThread();
mt.start();
System.out.println(101);
}
}
public class Test {
public static void main(String[] args) throws Exception{
MyThread mt = new MyThread();
mt.start();
mt.join();
System.out.println(101);
}
}
public class Test {
public static void main(String[] args) throws Exception{
MyThread mt = new MyThread();
mt.start();
mt.join();
Thread.sleep(3000);
mt.start();
}
}
public synchronized void start() {
if (started)
throw new IllegalThreadStateException();
started = true;
group.add(this);
start0();
}
[通过Thread实例的start()Q一个Thread的实例只能生一个线E]
class R implements Runnable{
private int x = 0;
public void run(){
for(int i=0;i<100;i++){
try{
Thread.sleep(10);
}catch(Exception e){}
System.out.println(x++);
}
}
}
正如它的名字一PRunnable的实例是可运行的Q但它自己ƈ不能直接q行Q它需要被Thread对象来包装才行运行:public class Test {
public static void main(String[] args) throws Exception{
new Thread(new R()).start();
}
}
public class Test {
public static void main(String[] args) throws Exception{
R r = new R();
for(int i=0;i<10;i++)
new Thread(r).start();
}
}
package debug;
import java.io.*;
import java.lang.Thread;
class MyThread extends Thread{
public int x = 0;
public void run(){
System.out.println(++x);
}
}
class R implements Runnable{
private int x = 0;
public void run(){
System.out.println(++x);
}
}
public class Test {
public static void main(String[] args) throws Exception{
for(int i=0;i<10;i++){
Thread t = new MyThread();
t.start();
}
Thread.sleep(10000);//让上面的U程q行完成
R r = new R();
for(int i=0;i<10;i++){
Thread t = new Thread(r);
t.start();
}
}
}
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
This can have two reasons:
java -Xms<initial heap size> -Xmx<maximum heap size>
Defaults are:
java -Xms32m -Xmx128m
You can set this either in the Java Control Panel or on the command line, depending on the environment you run your application.