创建线程的四种方式
1.继承Thread类,重写run()方法;
2.实现Runnable接口,重写run()方法;
3.实现Callable接口,重写call()方法;
4.使用线程池创建线程;
一、继承Thread类
步骤:
1.创建一个类继承Thread类,重写其run()方法,在run()方法中编写需要执行的任务;
2.创建继续Thread类的对象;
3.调用其对象的start()方法,该方法表示启动一个线程,线程处于就绪状态,如果获取到cpu执行权,则会调用run()方法,执行对应的任务;
public class ThreadDemo extends Thread{
private Thread t;
private String threadName;
ThreadDemo(String name)
{
threadName = name;
System.out.println("创建" + threadName );
}
@Override
public void run(){
System.out.println("运行"+threadName);
try{
for(int i = 4; i > 0; i--){
System.out.println("线程"+threadName+","+i);
Thread.sleep(50);
}
}catch (InterruptedException e){
System.out.println("线程"+threadName+"中断");
}
System.out.println("线程"+threadName+"退出");
}
public void start(){
System.out.println("启动"+threadName);
if(t==null){
t = new Thread(this,threadName);
t.start();
}
}
}
public class ThreadTest {
public static void main(String[] args) {
ThreadTest();
}
private static void ThreadTest() {
ThreadDemo T1 = new ThreadDemo("Thread-->1");
T1.start();
ThreadDemo T2 = new ThreadDemo("Thread-->2");
T2.start();
}
}
二、实现Runnable接口
步骤:
1.创建一个类,实现Runnable接口,重写run()方法,编写需要执行的代码;
2.创建一个Runnable接口实现类的对象;
3.将此对象作为形参传递到Thread类的构造器中,创建Thread类的对象,调用start()方法,启动线程;
public class RunnableDemo implements Runnable{
private Thread t;
private String threadName;
RunnableDemo(String name){
threadName = name;
System.out.println("创建 " + threadName);
}
@Override
public void run() {
System.out.println("运行 " + threadName);
try {
for (int i = 4; i > 0; i--) {
System.out.println("线程 " + threadName + ", " + i);
Thread.sleep(50);
}
}catch (InterruptedException e){
System.out.println("线程 " + threadName + " 运行中");
}
System.out.println("线程 " + threadName + " 运行结束");
}
public void start(){
System.out.println("启动线程"+ threadName);
if(t==null){
t=new Thread(this,threadName);
t.start();
}
}
}
public class ThreadTest {
public static void main(String[] args) {
runnableTest();
}
private static void runnableTest() {
RunnableDemo R1=new RunnableDemo("runnableThread-->1");
R1.start();
RunnableDemo R2=new RunnableDemo("runnableThread-->2");
R2.start();
}
}
三、实现Callable接口
步骤:
1.创建Callable接口的实现类,并实现call()方法,该方法具有返回值,并且可以抛异常;
2.创建Callable实现类的实例,并使用FutureTask类来包装Callable对象,该FutureTask对象封装了该Callable对象的call()方法的返回值;
3.使用FutureTask对象作为Thread对象的target创建并启动新线程;
4.调用FutureTask对象的get()方法来获取子线程执行结束后的返回值;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class CallableThreadTest implements Callable<Integer> {
public static void main(String[] args)
{
CallableThreadTest ctt = new CallableThreadTest();
FutureTask<Integer> ft = new FutureTask<>(ctt);
for(int i = 0;i < 10;i++)
{
System.out.println(Thread.currentThread().getName()+" 的循环变量i的值"+i);
if(i==5)
{
new Thread(ft,"有返回值的线程").start();
}
}
try
{
System.out.println("子线程的返回值:"+ft.get());
} catch (InterruptedException e)
{
System.out.println("发生异常");
} catch (ExecutionException e)
{
System.out.println("发生异常");
}
}
@Override
public Integer call() throws Exception
{
int i = 0;
for(;i<10;i++)
{
System.out.println(Thread.currentThread().getName()+" "+i);
}
return i;
}
}
Callable 和 Runnable接口的区别
- Callable规定的方法是call(),而Runnable规定的方法是run()。
- Callable的任务执行后可返回值,而Runnable的任务是不能返回值的。
- call()方法可抛出异常,而run()方法是不能抛出异常的。
四,线程池创建线程
我这里用newFixedThreadPool:创建一个固定数量的线程池
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadPool {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(5);
for (int i = 0; i < 2; i++) {
executor.execute(new Runnable() {
@Override
public void run() {
System.out.println("线程名: " + Thread.currentThread().getName() + " is running");
}
});
}
}
}