随着计算机技术的发展,编程模型也越来越复杂多样化。
如果不能从根本上更新当前CPU的架构(
所以,掌握多线程编程模型,不仅是目前提高应用性能的手段,
[第一需要弄清的问题]
如同程序和进程的区别,要掌握多线程编程,第一要弄清的问题是:
线程对象是可以产生线程的对象。
鉴于作者的水平,无法用更确切的词汇来描述它们的定义。
天下难事必始于易,天下大事必始于细。
让我们先从最简单的"单线程"来入手:(1)
class BeginClass{
public static void main(String[] args){
for(int i=0;i<100;i++)
System.out.println("Hello,
}
}
如果我们成功编译了该java文件,然后在命令行上敲入:
java BeginClass
现在发生了什么呢?每一个java程序员,
JVM进程被启动,在同一个JVM进程中,有且只有一个进程,
我们看到的是一个主线程在运行main方法,
之为单线程。这是JVM提供给我们的单线程环境,事实上,
主线程是JVM自己启动的,在这里它不是从线程对象产生的。
[接触多线程]
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");
}
}
执行这个程序,main方法第一行产生了一个线程对象,
main方法第二行产生了一个线程对象,并启动了一个线程。
main方法第三行,产生并启动一个线程后,
我们先不研究Thread对象的具体内容,
累了吧?为不么不继续了?
基于这种风格来介绍多线程,并不是每个人都喜欢和接受的,
在进入java平台的线程对象之前,我先插入两个基本概念。
[线程的并发与并行]
在单CPU系统中,系统调度在某一时刻只能让一个线程运行,
在上面包括以后的所有论述中,请各位朋友谅解,
[JAVA线程对象]
现在我们来开始考察JAVA中线程对象。
在JAVA中,要开始一个线程,有两种方式。
将Runable实例传给一个Thread实例然后调用它的st
在前面已经说过,线程对象和线程是两个完全不同的概念。
对于从很多书籍上可以看到的基础知识我就不用多说了。
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++);
}
}
}
如果我们生成MyThread的一个实例,
public class Test {
public static void main(String[] args) throws Exception{
MyThread mt = new MyThread();
mt.start();
}
}
不用说,最终会打印出0到99,现在我们稍微玩一点花样:
public class Test {
public static void main(String[] args) throws Exception{
MyThread mt = new MyThread();
mt.start();
System.out.println(101);
}
}
也不用说,在基础篇(一)中我们知道由于单CPU的原因,
public class Test {
public static void main(String[] args) throws Exception{
MyThread mt = new MyThread();
mt.start();
mt.join();
System.out.println(101);
}
}
好了,我们终于看到,mt实例对应的线程(
public class Test {
public static void main(String[] args) throws Exception{
MyThread mt = new MyThread();
mt.start();
mt.join();
Thread.sleep(3000);
mt.start();
}
}
当线程对象mt运行完成后,我们让主线程休息一下,
Exception in thread "main" java.lang.
也就是这种线程对象一时运行一次完成后,
public synchronized void start() {
if (started)
throw new IllegalThreadStateException();
started = true;
group.add(this);
start0();
}
一个Thread的实例一旦调用start()方法,
[通过Thread实例的start(),
那么如果要在一个实例上产生多个线程(也就是我们常说的线程池)
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++);
}
}
}
正如它的名字一样,Runnable的实例是可运行的,
public class Test {
public static void main(String[] args) throws Exception{
new Thread(new R()).start();
}
}
当然这个结果和mt.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();
}
}
x是实例对象,但结果是x被加到了999,
到这里我们做一个完整的例子来说明线程产生的方式不同而生成的线
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);//
R r = new R();
for(int i=0;i<10;i++){
Thread t = new Thread(r);
t.start();
}
}
}
上面10个线程对象产生的10个线程运行时打印了10次1。