线程简介
线程的存在就是充分使用CPU资源。
线程的五种状态
新建、就绪、运行、阻塞、死亡
新建
当程序通过new关键字创建一个线程之后,该线程就处于新建状态
线程的创建方式有三种:
- 继承Thread类创建线程类,重写run方法。
- 实现Runnable接口
- 实现Callable接口 该方式有返回值
就绪
当线程对象调用start() 方法,该线程就进入就绪状态。该状态线程并没有开始运行,只是表示该程序可以运行了。
注意事项:
调用start()启动线程而不是run。
如果直接调用run()系统会把run当成普通方法去执行,系统把线程让程一个普通对象,无法并发执行。
运行
当线程得到CPU资源就进入运行状态。
阻塞
线程进入阻塞状态的情况:
- 线程调用sleep()方法主动放弃所占用的处理器资源
- 线程调用了一个阻塞IO方法,在该方法返回之前,该线程被阻塞 如:读操作
- 线程试图获得一个同步监视器,但监视器正在被其他线程对象所持有。 如:同步代码块
- 线程等待某个通知(notify) 线程调用wait方法,线程进入挂起状态。
- 程序调用suspend()方法线程将被挂起。但这个方法容易导致死锁。
线程解除阻塞状态【重新进入就绪状态】:
- sleep()方法过了指定时间,睡眠时间结束
- 阻塞IO方法已经返回
- 该线程成功获得监视器资源
- 线程等待通知时,接收到一个通知 。 notify/notifyAll
- 线程调用resume恢复方法
死亡
线程死亡后,调用start()方法无法重新启动,死亡就是死亡
线程死亡的三种方式:
- 线程执行结束
- 线程抛出一个未捕获的异常
- 调用stop() 结束线程,但是容易导致死锁
线程实现方式一:继承Thread类
/** * @Author YangHe * @Date 2020/4/7 11:52 */ public class ThreadTest extends Thread { private int j; public ThreadTest(String name){ super(name); } public ThreadTest(ThreadGroup threadGroup,String name){ super(threadGroup,name); } @Override public void run() { for(;j<100;j++){ System.out.println(getName()+" "+j +" "+getThreadGroup().activeCount()); //显示该线程组活跃的线程数 if(j==50){ Thread.yield(); //当变量值为50 放弃当前资源 进入就绪状态 /* try { Thread.sleep(1000); //当变量值为50 睡眠一秒 进入阻塞状态 } catch (InterruptedException e) { e.printStackTrace(); }*/ } } } public static void main(String[] args) { ThreadTest t=new ThreadTest("6666666666"); t.setDaemon(true);//该线程设置为后台线程,所有线程结束该线程结束 t.start(); for(int i=0;i<100;i++){ System.out.println(Thread.currentThread().getName()+" "+i); if(i==20){ ThreadGroup threadGroup=new ThreadGroup("测试");//新建线程组 ,设置线程组名称 ThreadTest t1=new ThreadTest(threadGroup,"杨贺"); ThreadTest t2=new ThreadTest("李小艺"); t1.start(); t2.start(); } } } }
线程实现方式二:实现Runnable接口
/** * @Author YangHe * @Date 2020/4/7 11:52 */ public class RunnableTest implements Runnable{ private int j; @Override public void run() { for(;j<100;j++){ System.out.println(Thread.currentThread().getName()+" "+j); } } public static void main(String[] args) { for(int i=0;i<100;i++){ System.out.println(Thread.currentThread().getName()+" "+i); if(i==20){ RunnableTest r=new RunnableTest(); new Thread(r,"杨贺").start(); new Thread(r,"李小艺").start(); } } } }
线程实现方式三:实现Callable接口
import java.util.concurrent.Callable; import java.util.concurrent.FutureTask; /** * @Author YangHe * @Date 2020/4/7 15:47 */ public class CallableTest implements Callable<Integer> { @Override public Integer call() throws Exception { int i=0; for(;i<100;i++){ System.out.println(Thread.currentThread().getName()+" "+i); } return i; } public static void main(String[] args) throws InterruptedException { CallableTest callableTest=new CallableTest(); FutureTask<Integer> task=new FutureTask<Integer>(callableTest); for(int i=0;i<100;i++){ System.out.println(Thread.currentThread().getName()+"循环变量的值为 "+i); if(i==20){ Thread t1=new Thread(task,"李小艺"); t1.start(); t1.join(); //等待该线程执行完成,主线程再执行 } } try{ System.out.println("子线程的返回值为 "+task.get()); }catch (Exception e){ e.printStackTrace(); } } }
原文地址:https://www.cnblogs.com/yanghe123/p/12660474.html
时间: 2024-11-10 11:21:45