您的位置:首页 > 新闻 > 资讯 > 如何免费制作app软件_佛山网页开发_关键词搜索量查询工具_热门推广平台

如何免费制作app软件_佛山网页开发_关键词搜索量查询工具_热门推广平台

2024/12/26 20:16:19 来源:https://blog.csdn.net/lllsure/article/details/142632536  浏览:    关键词:如何免费制作app软件_佛山网页开发_关键词搜索量查询工具_热门推广平台
如何免费制作app软件_佛山网页开发_关键词搜索量查询工具_热门推广平台

目录

一.线程相关概念

1.程序(program)

2.进程

3.线程

4.其他相关概念

二.线程的创建

1.继承Thread

2.Runnable接口

3.多线程机制(重要)

4.start()

三.线程终止--通知

四.线程(Thread)方法

1.常用方法

2.yield和join

3.setDaemon

五.线程的生命周期

六.Synchronized 

1.线程同步机制

2.实现方法

2.1 同步代码块

2.2 同步方法

3.互斥锁

4.释放锁


一.线程相关概念

1.程序(program)

为了完成特定的任务,用某种语言编写的一组指令的集合。简单点说就是我们写的代码。

2.进程

进程是程序的一次执行过程,或是正在运行的一个程序。它是一个动态过程:产生 -> 存在 -> 消亡。

3.线程

由进程创建,是进程的一个实体,一个进程里有多个线程,线程也可以有子线程。

单线程:同一个时刻,只允许执行一个线程

多线程:同一个时刻,可以执行多个线程

4.其他相关概念

并发:同一时刻,多个任务交替执行,简单来说就是单核CPU实现多个任务。这里注意,单核CPU,一次就能进行一个任务,比如我们切换应用,看起来是都两个应用都在运行,实则是CPU的切换速度很快,快速切换完成的,不是在同时进行多个任务。

并行:同一个时刻,多个任务同时执行。多核CPU可以实现并行。这个跟上面的例子相对,每一个应用都有一个CPU工作。

二.线程的创建

1.继承Thread

我们可以通过继承Thread(线程)来创建线程。

当一个类继承了 Thread 类,该类就可以当线程使用。我们会重写run()方法,写上自己的业务代码。Thread 类 实现了 Runnable 接口的run方法

比如这里有一个Cat类:

class Cat extends Thread{public void run(){//重写run方法,实现我们需要的业务逻辑int time=1;while(true){System.out.println("time = "+time);try {//睡眠1sThread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}if(time==8){break;}time++;}}
}

现在Cat类可以当作线程使用,我们在main方法中使用了这个线程:
 

public static void main(String[] args) {//创建一个cat对象Cat cat=new Cat();cat.start();

2.Runnable接口

我们知道,Java一个类只能继承一个父类,如果我们要继承Thread的类已经继承了一个父类,那么怎么才能实现?

使用Runnable接口,使用这个接口后,实现run方法即可(前面说了Thread类的run方法是实现Runnable中的run方法)。

这里举一个Dog的例子,假设我们的Dog已经继承了Animal类了:

class Dog extends Animal implements Runnable{int count=0;@Overridepublic void run() { //普通方法while(true){System.out.println("count = "+count);try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}count++;}}
}

在main方法中的使用方法也不一样了:

Dog dog=new Dog();
//dog.start(); 这里不能调用start
Thread thread = new Thread(dog);
thread.start();

3.多线程机制(重要)

现在我们运行下面的代码:

public class Thread01 {public static void main(String[] args) throws InterruptedException {//创建一个cat对象Cat cat=new Cat();cat.start();for (int i = 1; i <= 8; i++) {Thread.sleep(1000);System.out.println("i = "+i);}}
}
class Cat extends Thread{public void run(){int time=1;while(true){System.out.println("time = "+time);try {//睡眠1sThread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}if(time==8){break;}time++;}}
}

查看输出的内容,我们发现输出的内容是交替出现的,这里就说明了一个事实:主线程与子线程交替执行。

当一个main线程启动一个子线程Thread-0,主线程不会阻塞,会继续执行。这也就是为什么我们可以看到其交替出现的原因。

当我们执行程序的时候(开了一个进程)先会开一个main线程,随后开一个子线程Thread-0,main线程结束后,子线程还会进行进行,直到结束为止。

总而言之,一个main线程结束,不代表整个进程都会结束,当全部线程结束的时候,进程才会结束。

4.start()

有人可能会发现,如果我们调用run()方法,一样可以打印,为什么要用start()而不用run()呢?

因为我们写的run() 方法,它只是一个普通的方法。我们调用start()方法,其底层会调用start0()方法,这个方法才是关键。真正实现多线程的效果是start0()

start0()是本地方法,是JVM调用的。

三.线程终止--通知

顾名思义,通知线程,让其关闭。当然,程序听不懂我们说的,但我们可以给它传一个值告诉它:停下吧。这里我们传入了一个布尔变量,让其控制线程的结束:

class T extends Thread{public boolean loop=true;public void run(){while(loop){try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("T 在运行");}}public void setLoop(boolean b) {loop=b;}
}

四.线程(Thread)方法

1.常用方法

方法说明
setName设置线程名称

getName

返回线程名称
start是该线程开始执行,JVM调用该线程的start0()方法
run调用线程对象 run 方法
setPriority更改线程的优先级
getPriority获取线程的优先级
sleep在指定的毫秒内让当前正在执行的线程休眠(暂停执行)
interrupt中断线程,注意不是结束

2.yield和join

方法说明
yield线程礼让,即让出CPU,让其它线程执行,但礼让的时间不确定,所以不一定礼让成功
join线程插队,线程插队一旦插队成功,肯定会先执行完插入的线程的所有任务

比如一开始线程A,B都在执行,想让A先暂停,让B先执行完。如果用yield方法,不一定能让A暂停,这取决于CPU资源占用量。但如果使用join,直接插队,B先把线程全部执行完,A就在那暂停。

3.setDaemon

方法说明
setDaemon设置为true,就是开启守护线程

用户线程(工程线程):当线程的任务全部执行完或通知方式结束

守护线程:一般是为工作线程服务的,当所有的用户线程结束,守护线程自动结束。常见守护线程:垃圾回收机制。

五.线程的生命周期

线程一共有六种状态,这里特别说明一下Runnable状态。

当进入到Runnable状态时,不是马上就开始运行了,是先变成Ready,被调度器选中才执行。

整个过程看图就可以理解。

六.Synchronized 

1.线程同步机制

在多线程编程中,一些敏感数据不允许被多个线程同时访问,此时就使用同步访问技术,保证数据在任何时刻,最多有一个线程访问,以保证数据的完整性。

锁是实现线程同步的一种常见手段。

2.实现方法

2.1 同步代码块

得到对象的锁,操作同步代码:

synchronized (对象){//需要被同步的代码
}
2.2 同步方法

放在方法声明中:

public synchronized void fun(){//需要被同步的代码
}

3.互斥锁

Java中引入了互斥锁的概念来保证共享数据操作的完整性。每个对象都有一个互斥锁的标记,这个标记用来确保在任一时刻,只有一个线程访问该对象。当一个对象用Synchronized 修饰时,表明该对象在任一时刻只能由一个线程访问。

但是同步也有局限性,那就是程序执行效率降低。比如一个本来一条路(有多个车道)可以自由通行,现在把它堵上了,安了一个卡口,一次就能通过一辆车,那么效率不就降低了。

如果同步的方法是非静态的,这时锁可以时this或者是其他对象。这里要注意,多线程操作每一个线程必须是同一个对象,如果是多个的话锁不就失效了嘛。比如说我们有一个Cat类,我们new了两个对象,一个cat1,一个cat2,这就不行。要new一个cat,然后用这个cat.start()两次,开两个线程才可以。

如果同步的方法是静态的,这时锁为当前类的本身,不能是this。

4.释放锁

我们不能只拿到了锁,用完了还要释放。下面是释放锁的几种途径:

1.当前线程的同步方法、同步代码块执行结束

2.当前线程在同步方法、同步代码块中遇到了break、return

3.当前线程在同步方法、同步代码块中出现了为处理的Error或Exception,导致异常结束

4.当前线程在同步方法、同步代码块中执行了线程对象的wait()方法,当前线程暂停,并释放锁

下面几种操作不会释放锁:

1.线程执行同步方法或同步代码块时,程序调用Thread.sleep()、Thread.yield()方法,暂停当前线程的执行,不会释放锁

2.线程执行同步代码块时,其他线程调用了该线程的suspend()方法将该线程挂起,不会释放锁

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com