本文讲解3点:
一. 对比单线程和多线程的区别
二. 创建多线程的2种方式:1. extends Thread 2.implements Runnable
三. 线程同步
一. 对比单线程和多线程的区别
1. 单线程
TestThread.java
public class TestThread {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
new ThreadDemo().run();
while(true){
System.out.println("main():"+Thread.currentThread().getName());
}
}
}
class ThreadDemo{
public void run(){
while(true){
System.out.println("run():"+Thread.currentThread().getName());
}
};
}
运行结果截图:

结果分析:其实这只是一个普通的单线程程序,所以main()方法里 while()的代码不会被执行到。而且,new ThreadDemo().run(); 是运行在main 线程内。
2. 多线程 (TestThread.java 改成一个多线程,对比运行结果)
TestThread2.java
public class TestThread2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
new ThreadDemo2().start();
while(true){
System.out.println("main():"+Thread.currentThread().getName());
}
}
}
class ThreadDemo2 extends Thread{
public void run(){
while(true){
System.out.println("run():"+Thread.currentThread().getName());
}
};
}
运行结果截图:

分析结果: 线程ThreadDemo2 和 线程main 交替执行,无序。
跟上面的TestThread.java对比,2点区别:1. TestThread.java 中ThreadDemo不是线程,因为没有extends Thread 也没有implements Runnable , 所以 TestThread.java 是普通的单线程程序。 而 TestThread中ThreadDemo2是线程,因为extends Thread . 2, ThreadDemo2 的启动线程的方法是start(),不是run().
-----------------------------------------------------------------------------------------------------------
二. 创建多线程的2种方式:1. extends Thread 2.implements Runnable
一). 用Thread类创建线程
1. 要将一段代码在一个新的线程上运行,该代码应该在一个类的run()函数中,并且run()函数所在的类是Thread的子类。倒过来看,我们要实现多线程,必须编写一个继承了Thread类的子类,子类要覆盖Thread类中的run()函数,在子类的run()函数中调用想在想在新线程上运行的程序代码。
2. 启动线程,要start()方法,而不会用run()方法。
3. 由于线程的代码段在run方法中,那么该方法执行完以后线程也就响应结束了,因而可以通过控制run方法中循环的条件来控制线程的结束。
1)前台线程,守护线程(也叫后台线程)和联合线程
1. 如果对某个线程对象在启动(调用start方法)之前调用了setDaemon(true)方法,这个线程就变成了守护线程。
2. 对于java程序来说,只要还有一个前台线程在运行,这个进程就不会结束;如果一个进程中只有守护线程运行,这个进程就会结束。‘
3. pp.join()的作用是把pp所对应的线程合并到调用pp.join();语句的线程中。
3.1 TestThread3.java
public class TestThread3 {
public static void main(String[] args) {
// TODO Auto-generated method stub
new ThreadDemo3().start();
}
}
class ThreadDemo3 extends Thread{
public void run(){
while(true){
System.out.println("run():"+Thread.currentThread().getName());
}
};
}
运行结构截图:

程序分析:main()方法执行完 new ThreadDemo3().start(); 这条语句后,main方法就就结束了,也就是main方法所在的main线程就结束了。注意:虽然main线程结束了,但是java程序并没有结束,因为前台线程ThreadDemo3 还在执行。此程序说明:java程序中,只要还有一个前台线程在运行,那么java程序都不会结束(虽然main线程已经结束了)。
3.2 TestThread4.java
public class TestThread4 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Thread tt = new ThreadDemo4();
tt.setDaemon(true);//设置线程为 守护线程
tt.start();
}
}
class ThreadDemo4 extends Thread{
public void run(){
while(true){
System.out.println("run():"+Thread.currentThread().getName());
}
};
}
运行结果截图:

程序结果分析:ThreadDemo4为守护线程,java程序中只有守护线程时,java程序马上结束。
4. TestThread5.java (解析 tt.join() , tt.join(10000) 的意义)
public class TestThread5 {
public static void main(String[] args) {
ThreadDemo5 tt = new ThreadDemo5();
tt.start();
int index = 0 ;
while(tr