Java實(shí)現(xiàn)線程的四種方式解析
概念
進(jìn)程
進(jìn)程指正在運(yùn)行的程序。確切的來(lái)說(shuō),當(dāng)一個(gè)程序進(jìn)入內(nèi)存運(yùn)行,即變成一個(gè)進(jìn)程,進(jìn)程是處于運(yùn)行過(guò)程中的程序,并且具有一定獨(dú)立功能
線程
線程是進(jìn)程中的一個(gè)執(zhí)行單元,負(fù)責(zé)當(dāng)前進(jìn)程中程序的執(zhí)行,一個(gè)進(jìn)程中至少有一個(gè)線程。一個(gè)進(jìn)程中是可以有多個(gè)線程的,這個(gè)應(yīng)用程序也可以稱之為多線程程序
程序
程序是含有指令和數(shù)據(jù)的文件,被存儲(chǔ)在磁盤(pán)或其他的數(shù)據(jù)存儲(chǔ)設(shè)備中,也就是說(shuō)程序是靜態(tài)的代碼。
主線程
jvm啟動(dòng)后,必然有一個(gè)執(zhí)行路徑(線程)從main方法開(kāi)始的,一直執(zhí)行到main方法結(jié)束,這個(gè)線程在java中稱之為主線程。
進(jìn)程調(diào)度策略
java主要用的是搶占式調(diào)度 進(jìn)程調(diào)度的方式參考進(jìn)程調(diào)度策略
創(chuàng)建線程的方法(四種)
1.匿名代碼塊
package com.it.threads;
public class Demo2 {
public static void main(String[] args) {
new Thread(){
@Override
public void run() {
for (int i = 0; i <1000 ; i++) {
System.out.println(Thread.currentThread().getName()+"---===>"+i);
}
}
}.start();
System.out.println("-----------main over--------------");
}
}
2.繼承Thread類
package com.it.threads;
/**
* 創(chuàng)建線程的步驟: 1 定義一個(gè)類繼承 Thread。
* 2 重寫(xiě) run 方法。
* 3 創(chuàng)建子類對(duì)象,就是創(chuàng)建線程對(duì)象。
* 4 調(diào)用 start 方法,開(kāi)啟線程并讓線程執(zhí)行,
* 同時(shí)還會(huì)告訴 jvm 去調(diào)用 run 方法。
* @version: $
*/
public class ThreadA extends Thread {
/**
* 線程的任務(wù)寫(xiě)在run方法中
*/
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
System.out.println(Thread.currentThread().getName() + "-->" + i);
}
}
public static void main(String[] args) {
ThreadA threadA = new ThreadA();
//設(shè)置線程的名字
threadA.setName("得力");
threadA.setPriority(10);
//設(shè)置線程的優(yōu)先級(jí)
ThreadA threadA1 = new ThreadA();
//設(shè)置線程的名字
threadA1.setName("得力1");
threadA1.setPriority(Thread.MIN_PRIORITY);
threadA1.start();
threadA.start();
System.out.println(threadA.getPriority());
System.out.println(threadA1.getPriority());
}
}
3.實(shí)現(xiàn)Runnable接口
package com.it.threads;
/**
* 1、定義類實(shí)現(xiàn) Runnable 接口。
* 2、覆蓋接口中的 run 方法。。
* 3、創(chuàng)建 Thread 類的對(duì)象
* 4、將 Runnable 接口的子類對(duì)象作為參數(shù)傳遞給 Thread 類的構(gòu)造函數(shù)。
* 5、調(diào)用 Thread 類的 start 方法開(kāi)啟線程。
* @version: $
*/
public class ThreadB implements Runnable {
@Override
public void run() {
for (int i = 0; i <1000 ; i++) {
System.out.println(Thread.currentThread().getName()+"---->"+i);
}
}
public static void main(String[] args) {
ThreadB threadB = new ThreadB();
Thread thread1 = new Thread(threadB,"aa");
Thread thread2 = new Thread(threadB,"bb1");
//啟動(dòng)線程
thread1.start();
thread2.start();
}
}
4.線程池
線程池,其實(shí)就是一個(gè)容納多個(gè)線程的容器,其中的線程可以反復(fù)使用,省去了頻繁創(chuàng)建線程對(duì)象的操作,無(wú)需反復(fù)創(chuàng)建線程而消耗過(guò)多資源。 實(shí)現(xiàn)線程池分為兩種
(1)實(shí)現(xiàn)Runnable
創(chuàng)建一個(gè)線程
package com.it.threadpool;
//方式一 實(shí)現(xiàn)Runnable接口
public class ThreadRunnable implements Runnable {
@Override
public void run() {
for (int i = 0; i <2; i++) {
System.out.println(Thread.currentThread().getName()+i+"進(jìn)入電影院");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+i+"離開(kāi)電影院");
}
}
}
創(chuàng)建線程池
package com.it.threadpool;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/*
* 創(chuàng)建線程池對(duì)象
創(chuàng)建Runnable接口子類對(duì)象
提交Runnable接口子類對(duì)象
關(guān)閉線程池
* */
public class ThreadRunnablePool {
public static void main(String[] args) {
//創(chuàng)建線程池對(duì)象 線程個(gè)數(shù) Executors:線程池創(chuàng)建工廠類 ExecutorService:線程池類
ExecutorService executorService = Executors.newFixedThreadPool(5);
//創(chuàng)建Runnable實(shí)例對(duì)象
ThreadRunnable threadRunnable = new ThreadRunnable();
//從線程池中獲取線程對(duì)象,然后調(diào)用run()
executorService.submit(threadRunnable);
executorService.submit(threadRunnable);
executorService.submit(threadRunnable);
executorService.shutdown();
}
}
(2)實(shí)現(xiàn)Callable接口
創(chuàng)建線程
package com.it.threadpool;
import java.util.concurrent.Callable;
public class ThreadCallable implements Callable {
@Override
public Object call() throws Exception {
System.out.println("我要一個(gè)教練:call");
Thread.sleep(2000);
System.out.println("教練來(lái)了: " +Thread.currentThread().getName());
System.out.println("教我游泳,交完后,教練回到了游泳池");
return null;
}
}
創(chuàng)建線程池
package com.it.threadpool;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadCallablePool {
public static void main(String[] args) {
//創(chuàng)建線程池
ExecutorService service = Executors.newFixedThreadPool(2);
//生成Callable對(duì)象
ThreadCallable threadCallable=new ThreadCallable();
//從線程池中獲取線程對(duì)象,然后調(diào)用run()
service.submit(threadCallable);
service.submit(threadCallable);
service.submit(threadCallable);
service.shutdown();
}
}
這兩種方式的區(qū)別如下:
- Callable定義的方法是call,而Runnable定義的方法是run。
- Callable的call方法可以有返回值,而Runnable的run方法不能有返回值,這是核心區(qū)別。
- Callable的call方法可拋出異常,而Runnable的run方法不能拋出異常。
舉一個(gè)例子說(shuō)明 創(chuàng)建一個(gè)線程用來(lái)求和
package com.it.threadpool;
import java.util.concurrent.Callable;
public class ThreadSum implements Callable<Integer> {
int x;
int y;
public ThreadSum(int x, int y) {
this.x = x;
this.y = y;
}
@Override
public Integer call() throws Exception {
return x+y;
}
}
創(chuàng)建線程池
package com.it.threadpool;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class ThreadSumPool {
public static void main(String[] args) {
ExecutorService executorService= Executors.newFixedThreadPool(5);
//Future用來(lái)接收call方法的返回值
Future future1=executorService.submit(new ThreadSum(200,500));
Future future2=executorService.submit(new ThreadSum(100,500));
Future future3= executorService.submit(new ThreadSum(200,600));
try {
//get()方法用來(lái)獲取返回值
System.out.println(future1.get());
System.out.println(future2.get());
System.out.println(future3.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
到此這篇關(guān)于Java實(shí)現(xiàn)線程的四種方式解析的文章就介紹到這了,更多相關(guān)Java實(shí)現(xiàn)線程內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java實(shí)現(xiàn)世界上最快的排序算法Timsort的示例代碼
Timsort?是一個(gè)混合、穩(wěn)定的排序算法,簡(jiǎn)單來(lái)說(shuō)就是歸并排序和二分插入排序算法的混合體,號(hào)稱世界上最好的排序算法。本文將詳解Timsort算法是定義與實(shí)現(xiàn),需要的可以參考一下2022-07-07
Mybatis 簡(jiǎn)單啟動(dòng)過(guò)程入門(mén)詳解
MyBatis是一個(gè)持久層框架,簡(jiǎn)化JDBC操作,SpringBoot集成MyBatis,通過(guò)創(chuàng)建項(xiàng)目、準(zhǔn)備數(shù)據(jù)、配置文件、實(shí)體類和接口,可以實(shí)現(xiàn)數(shù)據(jù)庫(kù)操作,使用@Mapper和@Select注解簡(jiǎn)化接口實(shí)現(xiàn),測(cè)試類使用@SpringBootTest和@Test注解啟動(dòng),本文介紹Mybatis啟動(dòng)過(guò)程,感興趣的朋友一起看看吧2025-03-03
如何利用postman完成JSON串的發(fā)送功能(springboot)
這篇文章主要介紹了如何利用postman完成JSON串的發(fā)送功能(springboot),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07
win10 下 idea2020安裝 JetBrains-agent.jar 包后閃退的問(wèn)題及解決辦法
這篇文章主要介紹了win10 下 idea2020安裝 JetBrains-agent.jar 包后閃退的解決辦法,本文給大家?guī)?lái)原因分析及解決方法,需要的朋友可以參考下2020-08-08
Java實(shí)現(xiàn)TCP和UDP協(xié)議詳解
這篇文章主要介紹了Java實(shí)現(xiàn)TCP和UDP協(xié)議詳解,TCP(傳輸控制協(xié)議)和UDP(用戶數(shù)據(jù)報(bào)協(xié)議)是兩種最常用的傳輸層協(xié)議,它們都用于在網(wǎng)絡(luò)上傳輸數(shù)據(jù),但是它們之間有很多不同之處,需要的朋友可以參考下2023-07-07
JavaEE實(shí)現(xiàn)基于SMTP協(xié)議的郵件發(fā)送功能
這篇文章主要為大家詳細(xì)介紹了JavaEE實(shí)現(xiàn)基于SMTP協(xié)議的郵件發(fā)送功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-05-05
Java工程的Resources目錄從基礎(chǔ)到高級(jí)應(yīng)用深入探索
這篇文章主要介紹了Java工程中的resources目錄,從基礎(chǔ)概念到高級(jí)應(yīng)用,涵蓋了如何創(chuàng)建、使用以及資源文件的加載方法,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2025-01-01

