1.理解线程对象和线程
在JAVA中,当JVM环境中运行一个程序时,JVM最先会产生一个主线程,由它来运行指定程序的入口点在这个程序中,即主线程从main方法开始运行。当main方法结束后,主线程运行完成。线程对象是JVM产生的一个普通的Object子类,而线程是CPU分配给这个对象的一个运行过程。
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");//产生并启动一个线程后,主线程自己也继续执行其它语句
}
}
2.理解产生线程对象的两种方式(继承Thread类和实现Runable接口)
直接调用Thread实例的start()方法:
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();
mt.join();
System.out.println(101);
}
}
一个Thread的实例一旦调用start()方法,这个实例的started标记就标记为true,事实中不管这个线程后来有没有执行到底,只要调用了一次start()就不能再次调用start()了,这意味着:[通过Thread实例的start(),一个Thread的实例只能产生一个线程]
所以若想实现线程池,就必须通过将Runable实例传给一个Thread实例然后调用它的start()方法。即把实现Runable接口后所产生的线程对象多次包装后就形成了线程池,示例如下:
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++);
}
}
}
public class Test {
public static void main(String[] args) throws Exception{
R r = new R();//产生一个r对象
for(int i=0;i<10;i++)
new Thread(r).start();
}
}
在上述代码运行完成之后,x将被加到999,这意味着所产生的10个线程是在同一个线程对象上完成的。