一、方式1——继承Thread类
1、实现步骤:
(1)创建一个继承了Thread类的子类
(2)在子类中重写run方法
(3)创建Thread对象
(4)调用Thread类中的start方法,开启新线程,执行重写后的run方法
//1.创建一个继承了Thread类的子类
public class ThreadTest extends Thread{
//2.子类中重写run方法
@Override
public void run() {
for(int i=0;i<5;i++)
System.out.println("新线程 去吃饭");
}
}
public class ThreadTestDemo {
public static void main(String[] args) {
//3.主线程中创建子类对象
ThreadTest test = new ThreadTest();
//4.创建的对象调用start方法,开启线程,执行重写后的run方法
test.start();
for(int j=0;j<5;j++){
System.out.println("main主线程 去睡觉");
}
}
}
main主线程 去睡觉
main主线程 去睡觉
main主线程 去睡觉
main主线程 去睡觉
main主线程 去睡觉
新线程 去吃饭
新线程 去吃饭
新线程 去吃饭
新线程 去吃饭
新线程 去吃饭
显然,此时main方法(主线程)能够更快的抢占CPU资源,可以通过以下代码使线程休眠
Thread.sleep(1000);//休眠1秒钟
由此,代码可以改写为:
//1.创建一个继承了Thread类的子类
public class ThreadTest extends Thread{
//2.子类中重写run方法
@Override
public void run() {
for(int i=0;i<5;i++)
System.out.println("新线程 去吃饭");
//try---catch 捕获异常,并打印异常性质,位置..
try{
Thread.sleep(1000);
}catch (Exception e){
e.printStackTrace();
}
}
}
public class ThreadTestDemo {
public static void main(String[] args) throws Exception{
//3.主线程中创建子类对象
ThreadTest test = new ThreadTest();
//4.创建的对象调用start方法,开启线程,执行重写后的run方法
test.start();
for(int j=0;j<5;j++){
System.out.println("main主线程 去睡觉");
//出现异常,抛!
Thread.sleep(1000);
}
}
}
main主线程 去睡觉
新线程 去吃饭
新线程 去吃饭
新线程 去吃饭
新线程 去吃饭
新线程 去吃饭
main主线程 去睡觉
main主线程 去睡觉
main主线程 去睡觉
main主线程 去睡觉
2、构造方法
(1)无参构造
ThreadTest test = new ThreadTest();
(2)有参构造:public Thread (String name);分配一个指定名字的线程对象
【1】子类重写有参构造
public ThreadTest(String name) {
super(name);
}
【2】创建子类对象时,调用有参构造器
ThreadTest test = new ThreadTest("线程一");
3、常用方法
(1)设置线程名字
test.setName("线程一");
(2)获取当前线程的名字
test.getName();
(3)返回正在执行线程的引用
Thread.currentThread();
二、方式二——实现Runnable接口
1、实现步骤
(1)创建一个Runnable接口的实现类
(2)在实现类中重写Runnable接口中的run方法
(3)创建Runnable接口的实现类对象
(4)创建Thread类对象,并通过构造方法传递Runnable接口实现类对象
(5)调用start方法,开启新线程
//1.创建一个Runnable接口的实现类
public class ThreadTest implements Runnable{
//2.在实现类中重写Runnable接口中的run方法
@Override
public void run() {
for(int i=0;i<5;i++)
System.out.println("新线程 去吃饭");
//try---catch 捕获异常,并打印异常性质,位置..
try{
Thread.sleep(1000);
}catch (Exception e){
e.printStackTrace();
}
}
}
public class ThreadTestDemo {
public static void main(String[] args) throws Exception{
//3.创建Runnable接口的实现类对象
ThreadTest test = new ThreadTest();
//4.创建Thread类对象,并通过构造方法传递Runnable接口实现类对象
Thread t=new Thread(test);
//5.调用start方法,开启线程,执行重写后的run方法
t.start();
for(int j=0;j<5;j++){
System.out.println("main主线程 去睡觉");
//出现异常,抛!
Thread.sleep(1000);
}
}
}
main主线程 去睡觉
新线程 去吃饭
新线程 去吃饭
新线程 去吃饭
新线程 去吃饭
新线程 去吃饭
main主线程 去睡觉
main主线程 去睡觉
main主线程 去睡觉
main主线程 去睡觉
2、这两种创建类型的区别
三、实现Callable接口
1、实现步骤
(1)Callable接口实现,需要规定泛型
(2)重写call()方法,方法体里写该线程需要执行的代码。其中返回值类型与第一部中规定的泛型类型一样
(3)创建FutureTask类的对象,传入Callable接口实现类的对象
(4)创建Thread类的对象,传入FutureTask类的对象
(5)启动线程.start()
(6)使用FutureTask类的对象调用get()方法获取到第二步中的返回值
2、代码实现
import java.util.concurrent.Callable;
//Callable接口实现
public class ThreadTest implements Callable<String> {
@Override
//重写call方法
public String call() throws Exception {
for(int i=0;i<5;i++){
System.out.println("Callable线程创建");
}
return "创建成功";
}
}
import java.util.concurrent.FutureTask;
public class ThreadTst {
public static void main(String[] args) {
//创建FutureTask对象,传入Callable实现类对象
FutureTask<String> stringFutureTask = new FutureTask<String>(new ThreadTest());
//创建Thread对象,传入FutureTask对象
Thread thread = new Thread(stringFutureTask,"我的线程");
//开启线程
thread.start();
for (int i = 0; i <5 ; i++) {
System.out.println("主线程循环");
}
//获取返回值
System.out.println(stringFutureTask.get());
}
}
四、线程池
1、实现步骤
(1)创建Runnable接口实现类
(2)重写run方法
(3)直接调用Excutor类的静态方法newFixedThread(),传入参数为需要创建的线程数。赋给ExcutorService类
(4)对象名.submit();传入参数为Runnable接口实现类对象。开启线程
(5)对象名.shutdown();销毁线程
2、代码实现
import java.util.concurrent.Callable;
//Callable接口实现
public class ThreadTest implements Callable<String> {
@Override
//重写call方法
public String call() throws Exception {
for(int i=0;i<5;i++){
System.out.println("Callable线程创建");
}
return "创建成功";
}
}
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ExecutorTst {
public static void main(String[] args) {
//静态方法,直接调用newFixedThreadPool()方法,赋给ExecutorService对象
ExecutorService pool = Executors.newFixedThreadPool(5);
//新创建的对象调用submit()方法,传入一个Runnable对象,开启线程
pool.submit(new ThreadTest());
//关闭,销毁线程
pool.shutdown();
}
}
匿名内部类创建线程
1、创建Thread匿名内部子类
//1.创建匿名内部子类
new Thread("我的线程"){
//2.重写run方法
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"吃饭");
}
//调用start方法
}.start();
2.创建Runnable匿名实现类
public Thread (Runnable target); 分配一个带有指定目标的线程对象
//1.创建匿名内部实现类
Runnable r = new Runnable() {
//2.重写run方法
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "吃饭");
}
};
//3.创建Thread对象,传入Runnable对象,调用start方法
new Thread(r).start();
3.Runnable匿名实现类另一种综合写法
pubic Thread (Runnable target,String name);分配一个带有指定目标的线程对象并指定名字。
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("吃饭");
}
},"线程一").start();