在java中可以通过继承Thread,并重写里面的run()方法实现线程,如下:
![](https://img-my.csdn.net/uploads/201303/07/1362662941_1932.jpg)
上面取了十多张票,但是只有六张,除非你家是铁路局的,否则你多出来的票是哪来的?
结果:
下面对程序进行剖析:
public class MyThread extends Thread{
private String number;
public MyThread(String number){
this.number=number;
}
@Override
public void run() {
for(int i=0;i<30;i++){
System.out.println("Thread"+number+" 已经运行,number i="+i);
}
}
}
调用过程:
public class ThreadDemo {
public static void main(String args[]){
MyThread mt1=new MyThread("线程1号");
MyThread mt2=new MyThread("线程2号");
MyThread mt3=new MyThread("线程3号");
mt1.start();//启动线程一号
mt2.start();//启动线程二号
mt3.start();//启动线程三号
}
}
通过start()方法启动线程,会通过JVM调用run()方法,但是为什么不直接调用run()方法呢?我们看一下java的源代码中是怎么写的
public synchronized void start() {
/**
* This method is not invoked for the main method thread or "system"
* group threads created/set up by the VM. Any new functionality added
* to this method in the future may have to also be added to the VM.
*
* A zero status value corresponds to state "NEW".
*/
if (threadStatus != 0)
throw new IllegalThreadStateException();
group.add(this);
start0();
if (stopBeforeStart) {
stop0(throwableFromStop);
}
}
private native void start0();
线程的启动会根据占用cpu的多少来启动线程,而上面的native所声明的start0()的作用就是调用操作系统的底层,进而可以对进程达到控制的目的.
下面介绍第二种方式implements runnable()
这种方法是通过实现runnable接口,所以你可以知道相比extends Thread,你可以多次实现各种接口,但是继承就不行了,你要是继承Thread,你就休想再继承别的东西了,所以这是使用runnable()的第一个好处,下面是使用Runnable的实现:
public class MyThread implements Runnable{
private String number;
public MyThread(String number){
this.number=number;
}
@Override
public void run() {
for(int i=0;i<30;i++){
System.out.println("Thread"+number+" 已经运行,number i="+i);
}
}
但是调用方式和Thread有所不同,实现Runnable这个接口要使用Thread的构造方法,截图一会传上来.然后启动public class ThreadDemo {
public static void main(String args[]){
MyThread mt1=new MyThread("线程1号");
MyThread mt2=new MyThread("线程2号");
MyThread mt3=new MyThread("线程3号");
new Thread(mt1).start();//启动线程一号
new Thread(mt2).start();//启动线程二号
new Thread(mt3).start();//启动线程三号
}
}
![](https://img-my.csdn.net/uploads/201303/07/1362662941_1932.jpg)
这两种方法的第二个区别就是使用Runnable()这个接口,可以实现资源共享:下面看例子:
package com.线程卖票1;
class MyThread extends Thread {
private int ticket=6;
@Override
public void run() {
for(int i=0;i<30;i++){
if(ticket>0){
System.out.println("卖票="+this.ticket--);
}
}
}
}
public class ThreadDemo {
public static void main(String args[]){
MyThread mt1=new MyThread();//一个线程
MyThread mt2=new MyThread();//两个线程
MyThread mt3=new MyThread();//三个线程
mt1.start();//启动线程一号
mt2.start();//启动线程二号
mt3.start();//启动线程三号
}
}
结果:
卖票=6
卖票=5
卖票=4
卖票=3
卖票=2
卖票=1
卖票=6
卖票=6
卖票=5
卖票=5
卖票=4
卖票=4
卖票=3
卖票=3
卖票=2
卖票=2
卖票=1
卖票=1
上面取了十多张票,但是只有六张,除非你家是铁路局的,否则你多出来的票是哪来的?
下面看implements Runnable()实现的:
package com.线程卖票2;
class MyThread implements Runnable {// 实现Runnable接口
private int ticket = 5; // 一共才5张票
public void run() {// 覆写run()方法
for (int i = 0; i < 50; i++) {// 表示循环10次
if (this.ticket > 0) {
System.out.println("卖票:ticket = " + this.ticket--);
}
}
}
}
public class ThreadDemo {
public static void main(String[] args) {
MyThread mt = new MyThread(); // 一个线程
new Thread(mt).start() ; // 开始卖票
new Thread(mt).start() ; // 开始卖票
new Thread(mt).start() ; // 开始卖票
}
}
结果:
卖票:ticket = 5
卖票:ticket = 2
卖票:ticket = 1
卖票:ticket = 4
卖票:ticket = 3
第二种实现方式的有点显而易见,就是可以实现资源共享!!!!!!!!!!!!!!!!!!!!
下面对程序进行剖析: