在了解线程的基本概念后,在介绍其他创建线程的方法。
未了解线程基本概念的附上链接:[link]https://blog.csdn.net/qq_41219356/article/details/105914254
1.使用Runnable接口创建进程
该接口通过由那些打算通过某一线程执行其实例的类来实现。Runnable为非Thread子类的类提供了一种激活方式,通过实例化某个Thread实例并将自身作为运行。
如果只想重写run()方法,而不重写其他的Thread方法,那么应使用Runnable接口。
// 第一个实现Runnable接口的类
public class ThreadRunnable01 implements Runnable {
public void run() {
Thread th=Thread.currentThread();
for(;1==1;) {
try {
th.sleep(500);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("id:"+th.getId()+"name"+th.getName()+"线程001");
}
}
}
//第二进程
public class ThreadRunnable02 implements Runnable {
public void run() {
Thread th = Thread.currentThread();
for (; 1 == 1;) {
try {
th.sleep(500);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("id:" + th.getId() + "name" + th.getName() + "线程002");
}
}
}
//Runable测试类
public class TestRunnable {
public static void main(String[] args) {
ThreadRunnable01 tr1=new ThreadRunnable01();
ThreadRunnable02 tr2=new ThreadRunnable02();
Thread th1=new Thread(tr1);
Thread th2=new Thread(tr2);
th1.start();
th2.start();
}
}
2.使用callable实现线程
接口Callable会返回结果并且可能抛出异常的任务,实现者定义了一个不带任何参数的叫做call的方法。
该接口下call方法有返回值
应用场景:
1:有返回结果,在某个线程的方法执行完成之后,需要告知调用者,结束了,例如我们想知道线程种代码的执行效率
2;面试:通过实现Callable接口,重写call方法,调用用到FutureTask
//创建类实现Callable接口
public class ThreadCallable01 implements Callable<String> {
public String call() throws Exception {
System.out.println("重写后的Callbale方法!");
return "call方法结束";
}
}
//测试Callable
public class TestCallable {
public static void main(String[] args) {
ThreadCallable01 tc = new ThreadCallable01();
FutureTask ft = new FutureTask(tc); // 包装callable对象
Thread th = new Thread(ft);
th.start();
try {
System.out.println(ft.get()); // 获取返回值并且输出
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
再说一下Thread和Runnable。
1、Thread是一个类,Runnable是一个接口
2、Thread类实现了Runnable接口,重写了run方法
3、Runnable是一个接口,定义一个类实现接口的同时还可以继承其他类;
4、Runnable适合多个相同的程序代码的线程去处理同一个资源,代码可以被多个线程共享
3.描述线程生命周期
新线程:当我们使用new关键字创建线程对象实例,那这个适合它只是作为一个对象存在,JVM没有为他分配CPU资源,
就绪状态:处于创建中的线程调用start方法将线程的状态转化为就绪状态,当前状态已经得到了其他的系统资源,在等待CPU资源
运行状态:就绪状态得到CPU资源后进入运行状态,执行run【call】方法中的代码段
等待/阻塞:线程运行的过程中被剥夺资源或则和我们在等待某些事件,这个就进入等待/阻塞状态,如supend()、sleep()被调用,或者线程使用wait()方法来等待条件变量,这个适合线程会释放所有的资源,但是并不释放锁,所以很容易引起死锁知道程序调用resume()方法回复线程运行。等待事件结束后或者得足够的资源就进入就绪态
死亡状态:当线程运行结束【正常结束】由JVM收回线程所占的资源