当前位置:网站首页>線程及線程池
線程及線程池
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("教我遊泳,交完後,教練回到了遊泳池");
}
}
边栏推荐
- Daily code 300 lines learning notes day 9
- Install and run tensorflow object detection API video object recognition system of Google open source
- Global and Chinese market of barrier thin film flexible electronics 2022-2028: Research Report on technology, participants, trends, market size and share
- MySQL development - advanced query - take a good look at how it suits you
- Statistics 8th Edition Jia Junping Chapter 2 after class exercises and answer summary
- Build your own application based on Google's open source tensorflow object detection API video object recognition system (II)
- Statistics 8th Edition Jia Junping Chapter 1 after class exercises and answers summary
- How to rename multiple folders and add unified new content to folder names
- Zhejiang University Edition "C language programming experiment and exercise guide (3rd Edition)" topic set
- Global and Chinese market of portable and handheld TVs 2022-2028: Research Report on technology, participants, trends, market size and share
猜你喜欢

Servlet

UCORE lab8 file system experiment report

软件测试有哪些常用的SQL语句?

Query method of database multi table link

The minimum number of operations to convert strings in leetcode simple problem

ucore lab5用户进程管理 实验报告

1. Payment system

ucore lab6 调度器 实验报告

Build your own application based on Google's open source tensorflow object detection API video object recognition system (II)

About the garbled code problem of superstar script
随机推荐
“Hello IC World”
Common Oracle commands
Face and eye recognition based on OpenCV's own model
Pointer -- eliminate all numbers in the string
Database monitoring SQL execution
Opencv recognition of face in image
Build your own application based on Google's open source tensorflow object detection API video object recognition system (II)
C language do while loop classic Level 2 questions
Global and Chinese markets of MPV ACC ECU 2022-2028: Research Report on technology, participants, trends, market size and share
[pointer] octal to decimal
Cc36 different subsequences
DVWA exercise 05 file upload file upload
Rearrange spaces between words in leetcode simple questions
Leetcode simple question: check whether the numbers in the sentence are increasing
Detailed introduction to dynamic programming (with examples)
刷视频的功夫,不如看看这些面试题你掌握了没有,慢慢积累月入过万不是梦。
基于485总线的评分系统双机实验报告
About the garbled code problem of superstar script
Which version of MySQL does php7 work best with?
想跳槽?面试软件测试需要掌握的7个技能你知道吗