当前位置: 首页 > 科技观察

夯实Java基础,一篇文章全解析线程问题

时间:2023-03-23 12:09:06 科技观察

1。什么是线程?操作系统支持多个应用程序并发执行。每个应用程序至少对应一个进程。通信一般采用管道通信、消息队列、共享内存等方式。当一个进程需要磁盘IO时,CPU切换到另一个进程,提高了CPU利用率。有了进程,为什么还需要线程?因为这个过程的成本太高了。启动一个新的进程必须分配一个独立的内存空间,建立一个数据表来维护它的代码段、堆栈段和数据段,这是一种昂贵的多任务工作方式。线程可以被认为是轻量级进程。线程之间使用相同的地址空间,切换线程的时间比切换进程的时间要短得多。进程是资源分配的最小单位,线程是CPU调度的最小单位。每个进程中至少有一个线程,同一个进程的所有线程共享进程的所有资源,多个线程可以完成多个不同的任务,也就是我们常说的并发多线程。2、如何创建线程创建线程常用的方法有四种,分别是:继承Thread类实现Runnable接口实现Callable接口。使用线程池来创建它。让我们看看如何使用代码创建它。2.1继承Thread类publicclassThreadDemo{publicstaticvoidmain(String[]args){Threadthread=newMyThread();thread.start();//启动线程}}classMyThreadextendsThread{@Overridepublicvoidrun(){System.out.println("关注公众号:一灯架构");}}输出结果:注意公众号:一灯架构的start方法用于启动一个线程,只能调用一次。run方法是线程的核心方法,业务逻辑写在run方法中。2.2实现Runnable接口publicclassThreadDemo{publicstaticvoidmain(String[]args){MyRunnablemyRunnable=newMyRunnable();线程thread1=newThread(myRunnable,"线程1");线程thread2=newThread(myRunnable,"thread2");thread1.start();//启动线程1thread2.start();//启动线程2}}classMyRunnableimplementsRunnable{privateintcount=5;@Overridepublicvoidrun(){while(count>0){System.out.println(Thread.currentThread().getName()+",注意公众号:一灯架构,"+count--);}}}输出结果:线程2,注意公众号:一灯架构,4线程1,遵循公众号:一灯架构,5线程1,遵循公众号:一灯架构,2线程1,遵循公众号:一灯架构,1线程2,重点关注公众号:一灯架构,3需要将Runnable实例放到Thread类中才能执行,Thread对象才是真正的线程对象。使用实现Runnable接口的方法创建线程,相比继承Thread类创建线程,优点是实现方法不存在类单一继承的限制。该实现方式更适合处理多线程共享数据的情况。2.3实现Callable接口publicclassThreadTest{publicstaticvoidmain(String[]args)throwsExecutionException,InterruptedException{MyCallablemyCallable=newMyCallable();FutureTaskfutureTask=newFutureTask(myCallable);线程thread=newThread(futureTask);thread.start();System.out.println(futureTask.get());}}classMyCallableimplementsCallable{@OverridepublicStringcall()throwsException{return"专注于公众号:OneLightArchitecture";}}输出结果:遵循公众号:一灯架构实现了Callable接口的线程实例对象,与FutureTask配合使用可以接收返回值。2.4使用线程池创建publicclassThreadDemo{publicstaticvoidmain(String[]args){ExecutorServiceexecutorService=Executors.newFixedThreadPool(10);executorService.execute(()->System.out.println("关注公众号:一灯架构"));}}输出结果:注意公众号:一登架构使用线程池创建线程是工作开发中最常见的方式。工作负载线程池有助于管理任务的调用、资源的创建和分配以重用线程和对象,提高使用效率。Wait),TIMED_WAITING(超时等待),BLOCKED(阻塞),TERMINATED(终止)。NEW(初始化)表示线程对象创建后还没有调用start方法。RUNNABLE(可运行)表示调用start方法后等待CPU调度。为了便于理解,RUNNABLE通常分为RUNNING(正在运行)和READY(就绪)。一个处于RUNNING(运行)状态的线程可以调用yield方法让出CPU时间片,然后与其他处于READY(就绪)状态的线程一起等待被调度。WAITING(等待)处于RUNNABLE状态的线程调用wait方法后,处于等待状态,需要被其他线程显式唤醒。TIMED_WAITING(超时等待)处于RUNNABLE状态的线程调用wait(long)方法后,处于等待状态,需要被其他线程显式唤醒。BLOCKED(阻塞)等待进入同步方法/代码块,处于阻塞状态。TERMINATED表示线程已经执行完毕。4.线程的常用方法说一下线程的常用方法。方法定义含义使用方法publicsynchronizedvoidstart(){...}启动线程MyThreadmyThread=newMyThread();myThread.start();publicstaticnativeThreadcurrentThread();获取当前线程实例对象Threadthread=Thread.currentThread();publicstaticnativevoidyield();放弃CPU时间片Thread.yield();publicstaticnativevoidsleep(longmillis);睡眠指定时间Thread.sleep(1L);publicvoidinterrupt(){……}中断线程MyThreadmyThread=newMyThread();我的线程.中断();publicstaticbooleaninterrupted(){...}判断线程是否已经中断MyThreadmyThread=newMyThread();布尔中断=myThread.isInterrupted();publicfinalnativebooleanisAlive();判断线程是否存活MyThreadmyThread=newMyThread();布尔值alive=myThread.isAlive();publicfinalStringgetName(){...}获取线程名MyThreadmyThread=newMyThread();Stringname=myThread.getName();publicStategetState(){...}获取线程状态MyThreadmyThread=newMyThread();Thread.Statestate=myThread.getState();publiclonggetId(){...}获取线程IDMyThreadmyThread=newMyThread();longid=myThread.getId();publicfinalvoidjoin(){...}在执行MyThread之前等待其他线程完成执行myThread=newMyThread();myThread.join();

最新推荐
猜你喜欢