程序分析:
1. tt.join() . 运行结果是: 刚开始 ThreadDemo5 tt线程 和 main线程交替运行,当main线程的 index 达到100时 , 因为tt.join,则表示 tt线程加入main线程,即tt线程和main线程合并成一个新的单线程。程序运行结果是: 刚开始 thread-0 , main 交替 , 当main线程的 index 达到100时,一直是 thread-0 到最后。 因为 当main线程的 index 达到100时,tt线程已经加入main线程,变成一个单线程,所以执行到tt线程时,要等到tt线程执行完才继续执行main线程。
2. tt.join(10000) . 运行结果是:刚开始 tt线程和main线程交替运行,当main线程的index 达到100时,则tt线程加入main线程成为一个新的单线程(10秒),10秒过后,tt线程和main线程再次各自成为单独的线程,形成刚开始的多线程。即:tt.join(10000) 表示:tt线程加入main线程形成新的单线程10秒钟。
二) . 用 实现Runnable 接口的方式创建线程
class ThreadDemo{ public void run(){}};
main(){ Thread tt = new Thread(new ThreadDemo()); tt.start(); }
三). 两种方式创建 线程的区别
eg: 火车站卖票100张,分四个窗口同时卖。比较使用extends Thread 和 implements Runnable 的区别。
对比结果:推荐使用Runnable ,几乎所有要实现多线程的程序,都推荐使用implements Runnable。
1. 使用extends Thread,java程序会默认尽量使用1个thread来卖票。
2. 使用 implements Runnable , java 程序会自动调用4个thread来卖票。
4.1 TestThread6.java
package com.thread;
public class TestThread6 {
public static void main(String[] args) {
new ThreadDemo6().start();
new ThreadDemo6().start();
new ThreadDemo6().start();
new ThreadDemo6().start();
}
}
class ThreadDemo6 /*implements Runnable*/ extends Thread{
int tickets = 100 ;
public void run(){
while(tickets>0){
// if(tickets>0)
{
System.out.println("run():"+Thread.currentThread().getName()+"is saling ticket "+tickets--);
}
}
};
}
运行结果:4个线程分别各卖100张票。

4.2 TestThread7.java
package com.thread;
public class TestThread7 {
public static void main(String[] args) {
ThreadDemo7 t = new ThreadDemo7();
new Thread(t).start();
new Thread(t).start();
new Thread(t).start();
new Thread(t).start();
}
}
class ThreadDemo7 implements Runnable{
int tickets = 100 ;
public void run(){
while(tickets>0){
// if(tickets>0)
{
System.out.println("run():"+Thread.currentThread().getName()+"is saling ticket "+tickets--);
}
}
};
}
运行结果:

---------------------------------------------------------------------------------------------------------------------------
三. 线程同步
线程同步的方法:使用synchronized 来实现 要确保线程安全的代码块 的原子性操作。
先看一段线程不安全的代码,以卖票100张为例。本例中4个线程卖100张票,则可能会打印出0和负数。正常应该是(100~1).
出现异常的原因是:当线程1执行到 while(tickets>0)这一句时,当时tickets = 1 ,这时操作系统突然切换到线程2(线程1并没有执行system.out.print(tickets--)),线程2此时判断tickets=1,并打印了“卖出票1”,tickets-- 变成了 0 ,这时 操作系统又切换到线程1让它继续执行system.out....(tickets--) ,打印出 "卖出票0" 。 同理,若线程3之前执行到"while(tickets>0)”时当时tickets=2,还没有执行system.out()这一句就被操作系统切换走了,而后来当又切换到线程3执行 system.out.print(tickets--) 时,tickets 可能当时已经变为-1了,所以,线程3 打印“卖出票-1” , 同理,可以退出打印“卖出票-2” 的情况。
分析原因:
因为 while(tickets>0)这一句 没有 和 循环体内的 代码块{system.out.println(tickets--)} 保持同步操作。即应该保持while(tickets>0)和{system.out.println(tickets--)}代码块操作的原子性。
注意:Thread.sleep(10) 这一句只是为了模拟出更容易出现线程不安全的状况,不加这一句,程序也是线程