多线程的三种创建方式
一、通过继承Thread类
1.创建一个继承Thread的子类;
2.重写Thread类的run()方法;
3.创建Thread的子类对象;
4.通过此对象调用start()方法;
package com.example.paoduantui.Thread;
import android.view.Window;
/**
*
* 创建三个窗口卖票,总票数为100张,使用继承自Thread方式
* 用静态变量保证三个线程的数据独一份
*
* 存在线程的安全问题,有待解决
*
* */
public class ThreadDemo extends Thread{
public static void main(String[] args){
window t1 = new window();
window t2 = new window();
window t3 = new window();
t1.setName("售票口1");
t2.setName("售票口2");
t3.setName("售票口3");
t1.start();
t2.start();
t3.start();
}
}
class window extends Thread{
private static int ticket = 100; //将其加载在类的静态区,所有线程共享该静态变量
@Override
public void run() {
while(true){
if(ticket>0){
// try {
// sleep(100);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
System.out.println(getName()+"当前售出第"+ticket+"张票");
ticket--;
}else{
break;
}
}
}
}
通过实现runable接口
1.创建了一个实现runable接口的实现类。
2.实现类去实现runable接口的抽象方法:run()
3.创建一个实现类对象。
4.将此对象作为参数传递到Thread的构造器中,创建Thread类对象
5.通过Thread对象调用start()方法;
package com.example.paoduantui.Thread;
public class ThreadDemo01 {
public static void main(String[] args){
window1 w = new window1();
//虽然有三个线程,但是只有一个窗口类实现的Runnable方法,由于三个线程共用一个window对象,所以自动共用100张票
Thread t1=new Thread(w);
Thread t2=new Thread(w);
Thread t3=new Thread(w);
t1.setName("窗口1");
t2.setName("窗口2");
t3.setName("窗口3");
t1.start();
t2.start();
t3.start();
}
}
class window1 implements Runnable{
private int ticket = 100;
@Override
public void run() {
while(true){
if(ticket>0){
// try {
// sleep(100);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
System.out.println(Thread.currentThread().getName()+"当前售出第"+ticket+"张票");
ticket--;
}else{
break;
}
}
}
}
通过实现callable接口
runable中重写run()不如callable中的call()强大;因为call()具有返回值;并且该方法可以抛异常;需要借助FutureTask类;
1.创建一个callable的实现类;
2.实现callable中的call();
3.创建一个实现类对象;
4.将创建的对象作为参数传递到FutureTask的构造器中,并创建FutureTask对象;
5.将FutureTask对象作为参数传递到Thread类中,并创建Thread对象,然后调用start方法;
package com.example.paoduantui.Thread;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
/**
* 创建线程的方式三:实现callable接口。---JDK 5.0新增
*是否多线程?否,就一个线程
*
* 比runable多一个FutureTask类,用来接收call方法的返回值。
* 适用于需要从线程中接收返回值的形式
*
* //callable实现新建线程的步骤:
* 1.创建一个实现callable的实现类
* 2.实现call方法,将此线程需要执行的操作声明在call()中
* 3.创建callable实现类的对象
* 4.将callable接口实现类的对象作为传递到FutureTask的构造器中,创建FutureTask的对象
* 5.将FutureTask的对象作为参数传递到Thread类的构造器中,创建Thread对象,并调用start方法启动(通过FutureTask的对象调用方法get获取线程中的call的返回值)
*
* */
//实现callable接口的call方法
class NumThread implements Callable{
private int sum=0;//
//可以抛出异常
@Override
public Object call() throws Exception {
for(int i = 0;i<=100;i++){
if(i % 2 == 0){
System.out.println(Thread.currentThread().getName()+":"+i);
sum += i;
}
}
return sum;
}
}
public class ThreadNew {
public static void main(String[] args){
//new一个实现callable接口的对象
NumThread numThread = new NumThread();
//通过futureTask对象的get方法来接收futureTask的值
FutureTask futureTask = new FutureTask(numThread);
Thread t1 = new Thread(futureTask);
t1.setName("线程1");
t1.start();
try {
//get返回值即为FutureTask构造器参数callable实现类重写的call的返回值
Object sum = futureTask.get();
System.out.println(Thread.currentThread().getName()+":"+sum);
} catch (ExecutionException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}