当前位置:网站首页>线程及线程池
线程及线程池
2022-07-06 09:25: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("教我游泳,交完后,教练回到了游泳池");
}
}
边栏推荐
- Global and Chinese markets of electronic grade hexafluorobutadiene (C4F6) 2022-2028: Research Report on technology, participants, trends, market size and share
- Pointers: maximum, minimum, and average
- ucore lab8 文件系统 实验报告
- 软件测试需求分析之什么是“试纸测试”
- Build your own application based on Google's open source tensorflow object detection API video object recognition system (I)
- How to learn automated testing in 2022? This article tells you
- Global and Chinese markets for complex programmable logic devices 2022-2028: Research Report on technology, participants, trends, market size and share
- Video scrolling subtitle addition, easy to make with this technique
- Four methods of exchanging the values of a and B
- Global and Chinese markets of PIM analyzers 2022-2028: Research Report on technology, participants, trends, market size and share
猜你喜欢
Statistics 8th Edition Jia Junping Chapter 4 Summary and after class exercise answers
UCORE lab8 file system experiment report
安全测试入门介绍
Fundamentals of digital circuits (I) number system and code system
软件测试面试要问的性能测试术语你知道吗?
Statistics 8th Edition Jia Junping Chapter 2 after class exercises and answer summary
Practical cases, hand-in-hand teaching you to build e-commerce user portraits | with code
Cadence physical library lef file syntax learning [continuous update]
Maximum nesting depth of parentheses in leetcode simple questions
Capitalize the title of leetcode simple question
随机推荐
[HCIA continuous update] working principle of static route and default route
ucore lab1 系统软件启动过程 实验报告
How to learn automated testing in 2022? This article tells you
My first blog
The number of reversing twice in leetcode simple question
The four connection methods of JDBC are directly coded
王爽汇编语言学习详细笔记一:基础知识
UCORE lab1 system software startup process experimental report
Software testing interview summary - common interview questions
MySQL development - advanced query - take a good look at how it suits you
How to solve the poor sound quality of Vos?
Logstack introduction and deployment -- elasticstack (elk) work notes 019
数字电路基础(二)逻辑代数
[pointer] use the insertion sorting method to arrange n numbers from small to large
Global and Chinese market of portable and handheld TVs 2022-2028: Research Report on technology, participants, trends, market size and share
[pointer] delete all spaces in the string s
Global and Chinese market for antiviral coatings 2022-2028: Research Report on technology, participants, trends, market size and share
The common methods of servlet context, session and request objects and the scope of storing data in servlet.
几款开源自动化测试框架优缺点对比你知道吗?
Es full text index