当前位置:网站首页>線程及線程池
線程及線程池
2022-07-06 15:10:00 【手可摘鑫晨】
1,線程概念
一個程序運行後至少有一個進程,一個進程中可以包含多個線程。
線程是進程中的一個執行單元,負責當前進程中程序的執行,一個進程中至少有一個線程。一個進程中是可以有多個線程的,這個應用程序也可以稱之為多線程程序。
2,線程調度
分時調度:所有線程輪流獲取CPU的使用權,平均分配每個線程占用的CPU的時間。
搶占式調度:優先級高的線程先使用CPU,如果線程優先級相同,
3,主線程
java使用java.lang.Thread類代錶線程,所有線程對象都必須是Thread類或其他子類的實例。每個線程的作用是完成一定的任務,實際上就是執行一段程序流即一段順序執行的代碼。Java使用線程執行體來代錶這段程序流。
4,實現線程的方式
public class xiancehng {
public static void main(String[] args) {
Thread thread = new SubThread();
thread.start();
}
}
//創建子線程
class SubThread extends Thread {
@Override
//重寫run方法
public void run() {
Thread t = Thread.currentThread();
String name = t.getName();
for (int i = 0; i < 10; i++) {
System.out.println(name + i);
}
}
}
public class xiangcheng2 {
public static void main(String[] args) {
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("hello word");
}
};
new Thread(runnable).start();
}
}
5,多線程原理
public class duoxiancheng1 {
public static void main(String[] args) {
System.out.println("這裏是main線程");
Thread thread = new ZiThread("小强");
thread.start();
for (int i = 0; i < 10; i++) {
System.out.println("旺財" + i);
}
}
}
class ZiThread extends Thread {
public ZiThread(String name) {
super(name);
}
@Override
public void run() {
Thread t = Thread.currentThread();
String name = t.getName();
for (int i = 0; i < 10; i++) {
System.out.println(name + i);
}
}
}
6,Thread類
構造方法:
public Thread(); 分配一個新的線程對象
public Thread(String name); 分配一個指定名字的新的線程對象
public Thread(Runnable target); 分配一個指定目標的新的線程對象
public Thread(Runnable target,String name); 分配一個指定目標的新的線程對象並指定名字
成員方法:
public String getName(); 獲取當前線程名稱
public void start(); 調用線程執行run方法
public void run(); 線程執行的任務在此處定義
public static void sleep(long millis); 當前正在執行的線程指定多少毫秒暫停
public static Thread currentThread(); 返回對當前正在執行的線程對象的引用
7,Thread和Runnable的區別
Runnable的優勢:
1,適合多個線程操作同一個任務對象。
2,可以避免java中的單繼承的局限性。
3,增加程序的健壯性,實現解耦操作,代碼可以被多個線程共享,代碼和線程獨立。
4,線程池只能放入實現Runable或Callable類線程,不能直接放入繼承Thread的類。可以避免java中的單繼承的局限性。
8,匿名內部類方式實現線程的創建
public static void main(String[] args) {
Runnable r = new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + i);
}
}
};
new Thread(r).start();
}
9,線程安全
案例:電影院要賣票,我們模擬電影院的賣票過程。假設要播放的電影是 “我和我的祖國”,本次電影的座比特共100個(本場電影只能賣100張票)。
我們來模擬電影院的售票窗口,實現多個窗口同時賣 “小猪佩奇”這場電影票(多個窗口一起賣這100張票)需要窗口,采用線程對象來模擬;需要票,Runnable接口子類來模擬。
public class xcanq {
public static void main(String[] args) {
Ticket ticket = new Ticket();
new Thread(ticket, "窗口1").start();
new Thread(ticket, "窗口2").start();
new Thread(ticket, "窗口3").start();
}
}
class Ticket implements Runnable {
private int ticket = 100;
@Override
public void run() {
while (true) {
synchronized (this) {
if (ticket > 0) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String name = Thread.currentThread().getName();
System.out.println(name + "正在賣" + ticket + "張票");
ticket--;
}
}
}
}
}
10,Lock鎖
使用方法:
public void lock();
public void unlock();
11,線程狀態
NEW | 新建狀態 | 一個線程創建以後,啟動之前,就處於該狀態。 |
TERMINATED | 消亡狀態 | 線程執行完任務後,處於該狀態。 |
RUNNABLE | 可運行狀態 | 線程正在整型任務,就處於該狀態。 |
BLOCKED | 阻塞狀態 | 獲取synchronized鎖對象失敗,處於該狀態。 |
WAITING | 無限等待狀態 | 獲取Lock鎖對象失敗,就處於該狀態。 |
TIMED_WAITING | 計時等待狀態 | 執行sleep方法,就處於該狀態。 |
12,sleep和wait的區別
13,wait和notify方法
(1)wait方法
線程不再活動,不再參與調度,進入 wait set 中,因此不會浪費 CPU 資源,也不會去競爭鎖了,這時的線程狀態即是 WAITING。
它還要等著別的線程執行一個特別的動作,也即是“通知(notify)”在這個對象上等待的線程從wait set 中釋放出來,重新進入到調度隊列(ready queue)中。
(2)notify方法
則選取所通知對象的 wait set 中的一個線程釋放;例如,餐館有空比特置後,等候就餐最久的顧客最先入座。
(3)notifyAll方法
釋放所通知對象的 wait set 上的全部線程。
注意:
(1)wait方法與notify方法必須要由同一個鎖對象調用。因為:對應的鎖對象可以通過notify喚醒使用同一個鎖對象調用的wait方法後的線程。
(2)wait方法與notify方法是屬於Object類的方法的。因為:鎖對象可以是任意對象,而任意對象的所屬類都是繼承了Object類的。
(3)wait方法與notify方法必須要在同步代碼塊或者是同步函數中使用。因為:必須要通過鎖對象調用這2個方法。
14,線程的通信
案例:
包子鋪線程生產包子,吃貨線程消費包子。當包子沒有時(包子狀態為false),吃貨線程等待,包子鋪線程生產包子(即包子狀態為true),並通知吃貨線程(解除吃貨的等待狀態),因為已經有包子了,那麼包子鋪線程進入等待狀態。
接下來,吃貨線程能否進一步執行則取决於鎖的獲取情况。如果吃貨獲
取到鎖,那麼就執行吃包子動作,包子吃完(包子狀態為false),並通知包子鋪線程(解除包子鋪的等待狀態),吃貨線程進入等待。包子鋪線程能否進一步執行則取决於鎖的獲取情况。
定義包子類:
public class Baozi {
String pier;
String xianer;
boolean flag = false;
}
定義吃貨線程:
public class Chihuo extends Thread {
private Baozi bz;
public Chihuo(String name, Baozi bz) {
super(name);
this.bz = bz;
}
@Override
public void run() {
while (true) {
synchronized (bz) {
if (bz.flag == true) {
System.out.println("吃貨正在吃"+bz.pier+bz.xianer+"包子");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
bz.flag = false;
bz.notify();
} else {
try {
bz.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
}
定義包子鋪線程:
public class BaoZiPu extends Thread {
private Baozi bz;
public BaoZiPu(String name, Baozi bz) {
super(name);
this.bz = bz;
}
@Override
public void run() {
int count = 0;
while (true) {
synchronized (bz) {
if (bz.flag == true) {
try {
bz.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else {
System.out.println("包子鋪開始做包子");
if (count % 2 == 0) {
bz.pier = "冰皮";
bz.xianer = "五仁";
} else {
bz.pier = "薄皮";
bz.xianer = "牛肉大葱";
}
count++;
bz.flag = true;
System.out.println("包子造好了:" + bz.pier + bz.xianer);
System.out.println("吃貨來吃吧");
bz.notify();
}
}
}
}
}
測試線程:
public class Test {
public static void main(String[] args) {
Baozi bz = new Baozi();
Chihuo ch = new Chihuo("吃貨", bz);
BaoZiPu bzp = new BaoZiPu("包子鋪",bz);
bzp.start();
ch.start();
}
}
15,線程池概念
其實就是一個容納多個線程的容器,其中的線程可以反複使用,省去了頻繁創建線程對象的操作,無需反複創建線程而消耗過多資源。
16,線程池的好處
(1)降低資源消耗。减少了創建和銷毀線程的次數,每個工作線程都可以被重複利用,可執行多個任務。
(2)提高響應速度。當任務到達時,任務可以不需要的等到線程創建就能立即執行。
(3)提高線程的可管理性。可以根據系統的承受能力,調整線程池中工作線線程的數目,防止因為消耗過多的內存,而把服務器累趴下(每個線程需要大約1MB內存,線程開的越多,消耗的內存也就越大,最後死機)。
17,線程池的使用
創建線程池:public static ExecutorService newFixedThreadPool(int nThreads)
使用線程池對象:public Future<?> submit(Runnable task)
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class xcc {
public static void main(String[] args) {
ExecutorService service = Executors.newFixedThreadPool(2);
MyRunnable r = new MyRunnable();
service.submit(r);
}
}
class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("我要一個教練");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("教練來了: " + Thread.currentThread().getName());
System.out.println("教我遊泳,交完後,教練回到了遊泳池");
}
}
边栏推荐
- How to use Moment. JS to check whether the current time is between 2 times
- Detailed introduction to dynamic programming (with examples)
- DVWA exercise 05 file upload file upload
- MySQL数据库(二)DML数据操作语句和基本的DQL语句
- Oracle foundation and system table
- Global and Chinese markets of Iam security services 2022-2028: Research Report on technology, participants, trends, market size and share
- Pedestrian re identification (Reid) - Overview
- 如何成为一个好的软件测试员?绝大多数人都不知道的秘密
- Nest and merge new videos, and preset new video titles
- Fundamentals of digital circuits (II) logic algebra
猜你喜欢
Statistics 8th Edition Jia Junping Chapter 4 Summary and after class exercise answers
Dlib detects blink times based on video stream
Vysor uses WiFi wireless connection for screen projection_ Operate the mobile phone on the computer_ Wireless debugging -- uniapp native development 008
In Oracle, start with connect by prior recursive query is used to query multi-level subordinate employees.
Fundamentals of digital circuits (I) number system and code system
Keil5 MDK's formatting code tool and adding shortcuts
软件测试方法有哪些?带你看点不一样的东西
Fundamentals of digital circuits (III) encoder and decoder
Réponses aux devoirs du csapp 7 8 9
软件测试有哪些常用的SQL语句?
随机推荐
Pointer -- eliminate all numbers in the string
The four connection methods of JDBC are directly coded
线程及线程池
STC-B学习板蜂鸣器播放音乐
如何成为一个好的软件测试员?绝大多数人都不知道的秘密
Face and eye recognition based on OpenCV's own model
Flash implements forced login
Daily code 300 lines learning notes day 9
[pointer] find the length of the string
UCORE lab2 physical memory management experiment report
Transplant hummingbird e203 core to Da Vinci pro35t [Jichuang xinlai risc-v Cup] (I)
Global and Chinese markets of electronic grade hexafluorobutadiene (C4F6) 2022-2028: Research Report on technology, participants, trends, market size and share
Emqtt distribution cluster and node bridge construction
JDBC 的四种连接方式 直接上代码
MySQL数据库(五)视 图 、 存 储 过 程 和 触 发 器
[pointer] find the value of the largest element in the two-dimensional array
Zhejiang University Edition "C language programming experiment and exercise guide (3rd Edition)" topic set
Install and run tensorflow object detection API video object recognition system of Google open source
UCORE lab7 synchronous mutual exclusion experiment report
软件测试行业的未来趋势及规划