创建多线程的第一种方式:Thread类
//继承Thread类,并重写Thread类中的run()方法。
class ThreadCreate extends Thread{
//public static void main(String [] args){ 没有必要写主函数,编译还是可以通过的
private int i = 0;//初始化的值,应该考虑到输出几次,如果从最大值开始考虑,for循环里面用的应该是i--
@Override//严格区分大小写
public void run(){//run()方法的方法体,代表了要运行的任务,称之为线程执行体
for(int i = 0;i < 20;i++){
if(i == 11){//等于"11",以便标识,下面的文字也是同理
System.out.println(Thread.currentThread().getName()+"..."+i+"这是run()方法控制的输出语句");
}
}
}
//}
}
//运行代码
class ThreadRun{
/*
public static void main(String [] args){
ThreadCreate t = new ThreadCreate();
t.run();
}
这个只是调用了run()方法
*/
public static void main(String [] args){
for(int i = 0;i < 20;i++){
//System.out.println(Thread.currentThread().getName()+"..."+i);
if(i == 10){//也就是说,if控制的对象其实并不是主线程,而是,确保在新的线程在主线程中只执行一次
//System.out.println(Thread.currentThread().getName()+"..."+i);
/*如果代码放到了这个位置,主线程只会输出main...10,而其他线程仍然输出至19,说明if语句并没有
控制其他线程,其他线程执行的内容为线程执行体
*/
Thread t1 = new ThreadCreate();//线程进入新建状态
Thread t2 = new ThreadCreate();
t1.start();//线程进入就绪状态
t2.start();
System.out.println(Thread.currentThread().getName()+"..."+i+"这是主线程控制的输出语句");
/*本来以为其他线程没有受if控制,是因为线程没有创建,但最终的执行结果和上面一样。
引:所以如果真的理解"线程执行体"的概念,应该在run()方法的任务里,对语句进行控制。
输出结果:
Thread-0...11这是run()方法控制的输出语句
Thread-1...11这是run()方法控制的输出语句
main...10这是主线程控制的输出语句
*/
}
}
}
}
创多线程的第二种方式:Runnable接口
/*利用Runnable接口来实现多线程的创建*/
//创建一个类实现Runnable接口
class MyRunnable implements Runnable{
private int i = 0;
public void run(){//该run()方法仍然是线程的执行体
for(i = 0;i < 20;i++){
System.out.println(Thread.currentThread().getName()+"..."+i);
}
}
}
//执行代码
class RunnableTest{
public static void main(String [] args){
for(int i = 0;i < 20;i++){
System.out.println(Thread.currentThread().getName()+"..."+i);
if(i == 15){
Runnable r1 = new MyRunnable();
Runnable r2 = new MyRunnable();//Runnable接口指向子类对象
Thread t1 = new Thread(r1);//Runnalbe的子类实现作为参数,Thread类重载的构造函数进行初始化,创建对象t1
Thread t2 = new Thread(r2);
t1.start();
t2.start();//最后还是通过Thread对象进入线程就绪状态
}
}
}
}
两者的区别:
class MyRunnable implements Runnable{
private int i = 0;
public void run(){
System.out.println("MyRunnable...run...");
for(i = 0;i < 20;i++){
System.out.println(Thread.currentThread().getName()+"..."+i);
}
}
}
class MyThread extends Thread{
private int i = 0;
public MyThread(Runnable r){//Thread类里其实有一个以Runnable为参数的构造函数
super(r);//显式的super(r);
}
public void run(){
System.out.println("MyThread...run...");//通过输出发现执行的是MyThread里的run()方法
for(i = 0;i < 20;i++){
System.out.println(Thread.currentThread().getName()+"..."+i);
}
}
}
class ThreadAndRunnable{
public static void main(String [] args){
for(int i = 0;i < 20;i++){
System.out.println(Thread.currentThread().getName()+"..."+i);
if(i == 15){
Runnable r = new MyRunnable();
Thread t = new MyThread(r);
t.start();
}
}
}
}
查看API:
Thread类中对Runnable接口中的方法run()的实现:
@Override
public void run(){
if(target != null){
target.run();
}
}
当执行到Thread类的run()方法的时候,首先会判断target是否存在,存在则执行run()方法,也就是实现了Runnable接口并重写run()方法。