多线程
学习多线程之前,我们要先了解什么是线程,但是了解线程之前,我们首先要了解什么是进程,线程依赖于进程存在
1.进程
概述:正在运行的程序叫做进程。进程是系统进行资源分配和调用的独立单位。每一个进程都有它自己的内存空间和系统资源
多进程的意义:
单进程的计算机只能做一件事情,而现代的计算机都是多进程,也就是可以同时做很多事情。
举例:一边记笔记,一边执行代码,一边屏幕广播
意义:同一个时间可以同时进行多个任务,提高工作效率,并且提高CPU的使用率
思考:
我电脑是单核处理器,我一边做笔记,一边屏幕广播,他们是同时进行的吗:
一个CPU在一个时间点上,只能做一件事情,他在执行多个进程时进行了程序间的高速切换,这个时间非常,所以我们的感官是进程是同时进行的
2.线程
在同一个线程中,可以执行多个任务,而每一个任务,就是一个线程
概述:
线程是程序的执行的单元。也是执行路径。线程也是程序使用CPU资源的基本单位
单线程:
只有一个执行路径或一个执行单元
多线程:
有多条执行路劲或多个执行单元
多线程的意义:
1.线程的执行是抢占式,他用去抢占CPU的资源。一个多线程在执行时,如果一些线程必须等待时,CPU资源就可以交给其他线程去使用,这样就提高了CPU使用率。
2.对于线程来说,如果他是多线程,在抢占Cpu资源时,就有更大的几率抢占到CPU的资源。提高程序的执行率。
3.在抢占CPU资源时,是具有随机性的,我们不敢保证拿一个线程在哪一个短时间可以抢到CPU资源
3.并行,并发
并行:
多个处理器 或 多核处理器同时处理多个不同任务
并发:
一个处理器同时处理多个任务
举例:
1.并发就相当于一个人同时吃三个馒头,并行就相当于三个人分别吃一个馒头
2.我正在吃饭,突然来电话,但是我直到吃完饭,我才去接电话,就代表我不支持并发,也不支持并行
我正在吃饭,突然来电话,我停止吃饭,去接电话,接完电话,接着吃饭,这代表我支持并发
我正在吃饭,突然来电话,我边吃饭,-边打电话,这就代表我支持并行.
4.如何实现多线程
由于线程是依赖于进程存在的,所以首先我们要创建一个进程.而进程是由系统来创建的,所以我们需要调用系统的某些功能来创建进程,但是是不能调用系统功能的.虽然程序不能调用系统功能,但是它可以调用C/C++写好的程序来创建进程,进而实现多线程.
JAVA将C/C++写好的代码封装到-个类中,然后通过这个类就可以调用创建进程,线程的这些功能,然后间接的实现多线程.
JAVA提供的这个类叫做Thread类。
通过API,我们知道创建线程有两种方式
一种方法是将类声明为Thread 的子类。该子类应重写Thread类的run方法
方式一:
1.自定义线程MyThrea类,继承Thread
2.MyThread类重写run();
3.创建MyThrea类的对象
4.启动线程start()
package unit.wdit.thread;
public class MyThread extends Thread{
@Override
public void run(){
for (int i =0;i< 500 ;i++){
System.out.println(getName()+"-"+i);
}
}
}
class MyThreadDemo{
public static void main(String[] args) {
MyThread myThread = new MyThread();
MyThread myThread1 = new MyThread();
// myThread.run();//普通方法
// myThread1.run();
myThread.start();//啓動綫程
myThread1.start();
}
}
4.1设置线程优先级
两种线程调度模型
1.分时调度:所有线程轮流使用CPU的使用权,平均分配每个线程占用CPU时间片。
2.抢占式调度:该调度模型会优先让优先级高的线程使用cpu,如果优先级相同,则随机选择。优先级高的线程只代表它抢到CPU的概率比较大。
package unit.wdit.thread;
/**
* 1.自定义线程MyThrea类,继承Thread
* 2.MyThread类重写run();
* 3.创建MyThrea类的对象
* 4.启动线程start()
*
* 綫程重命名:
* 1.setName(Steing name)
* 2.有參構造:在子类中声明有参构造并显式的指定访问父类的有参构造
*
*/
public class MyThread extends Thread{
public MyThread(String name){
super(name);
}
@Override
public void run(){
for (int i =0;i< 500 ;i++){
System.out.println(getName()+"-"+i);
}
}
}
class MyThreadDemo{
public static void main(String[] args) {
MyThread myThread = new MyThread("唐大帥哥");
MyThread myThread1 = new MyThread("老王");
// myThread.run();//普通方法
// myThread1.run();
myThread.start();
myThread1.start();
System.out.println(Thread.currentThread().getName());
}
}
获取优先级的方法:
public final getPriority():返回该线程的默认优先级
默认优先级为:5 范围:1-10
设置优先级的方法:
public final void setPriority(int newPriority):更改线程的优先级。
package unit.wdit.thread;
/**
* 1。自定义线程类,继承Thread
* 2。重写run方法(重写内容就是)
* 3.创建自定义线程类的对象
* 4.start()
*/
public class MyThread2 extends Thread{
public MyThread2(String s) {
super(s);
}
@Override
public void run(){
for (int i =0;i< 10 ;i++){
System.out.println(getName()+"-"+i);
}
}
}
class MyThreadDemo2{
public static void main(String[] args) {
MyThread2 myThread2 = new MyThread2("唐康");
MyThread2 myThread1 = new MyThread2("唐");
//**public final void setPriority(int newPriority)**:更改线程的优先级。
//myThread1.setPriority(10);
int priority = myThread1.getPriority();
//**public final getPriority()**:返回该线程的默认优先级
System.out.println(priority);
int priority1 = myThread2.getPriority();
System.out.println(priority1);
}
}
4.2线程控制
线程睡眠
public static void sleep(long millis)
package unit.wdit.thread;
/**
* 线程睡眠
* sleep()在那个线程中调用,阻塞哪个方法
*/
public class SleepDemo extends Thread{
public SleepDemo(String name){
super(name);
}
@Override
public void run(){
for (int i =0;i< 10 ;i++){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(getName()+"-"+i);
}
}
}
class SleepTest{
public static void main(String[] args) {
SleepDemo sleepDemo = new SleepDemo("线程1");
sleepDemo.start();
}
}
线程加入
public final void join(long millis):该方法是让调用该方法的线程执行完毕后,再去执行其他线程。
package unit.wdit.thread;
/**
* 线程加入
* •public final void join(long millis):该方法是让调用该方法的线程执行完毕后,再去执行其他线程。
*/
public class JionDemo {
public static void main(String[] args) {
MyThread3 myThread3 = new MyThread3("线程一");
MyThread3 myThread2 = new MyThread3("线程二");
MyThread3 myThread1 = new MyThread3("线程三");
System.out.println("程序开始");
myThread3.start();
try {
//设置时间 最多等待它这么多时间
myThread3.join(5000);
//myThread3.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
myThread2.start();
myThread1.start();
}
}
class MyThread3 extends Thread{
public MyThread3(String name){
super(name);
}
@Override
public void run(){
for (int i =0;i< 20 ;i++){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(getName()+":"+i);
}
}
}
线程礼让
**public static void yield()😗*线程礼让可以让线程间的抢占趋于和平,就是一运行一下,我运行一下,但是仅仅是让抢占不激烈,并不是说一-定每个线程的执行时间或执行次数相同.
package unit.wdit.thread;
/**
* 线程礼让
*/
public class YieldDemo {
public static void main(String[] args) {
MyThread4 m = new MyThread4("线程一");
MyThread4 m2 = new MyThread4("线程二");
MyThread4 m3 = new MyThread4("线程三");
m.start();
m2.start();
m3.start();
}
}
class MyThread4 extends Thread{
public MyThread4(String name){
super</