文章目录
- 前言
-
- 一、线程和进程的联系和区别是什么?
- 二、什么是前台线程,什么是后台线程?
- 三、创建线程有几种方法,它们之间的区别是什么?
- 四、线程的生命周期有哪些状态,哪些方法可以改变这些状态?
- 五、什么是线程安全?为什么会产生线程安全问题?如何解决线程安全问题?
- 六、什么是线程的同步通信?同步通信如何实现?
- 七、什么是死锁?
- 八、如何让某个对象的A方法内的一个代码块和另一个方法B实现同步?
- 九、设计一个程序产生两个线程A与B,B线程执行10秒钟后,被A中止。
- 十、volatile 关键字有什么作用?
- 十一、编写Java程序模拟烧水泡茶最优工序。
- 十二、编写一-个基于多线程的生产者/消费者Java应用, 各产生10个生产者和消费者线程,共享一个缓冲区队列(长度自设),生产者线程将产品放入到缓冲区,消费者线程从缓冲区取出产品。(选做)
前言
本文章主要讲述了java线程的相关内容
提示:以下是本篇文章正文内容,下面案例可供参考
一、线程和进程的联系和区别是什么?
区别:
(1)一个进程就是一个执行中的程序,而每一个进程都有自己独立的一块内存空间、一组系统资源,每一个进程的内部数据和状态都是完全独立的。
(2)Java程序执行中的单个顺序的流控制称为线程,多线程则指一个进程中可以同时运行多个不同的线程,执行不同的任务。
(3)同类的多个线程共享一块内存空间和一组系统资源,而线程本身的数据通常只有微处理器的寄存器数据,以及一个供程序执行时使用的堆栈。所以系统在产生一个线程,或者在各个线程之间切换时,负担要比进程小的多
联系:
一个进程可以包括多个线程。
二、什么是前台线程,什么是后台线程?
main()函数即主函数,是一个前台线程,前台进程是程序中必须执行完成的,而后台线程则是java中所有前台结束后结束,不管有没有完成,后台线程主要用与内存分配等方面。
前台线程和后台线程的区别和联系:
1、后台线程不会阻止进程的终止。属于某个进程的所有前台线程都终止后,该进程就会被终止。所有剩余的后台线程都会停止且不会完成。
2、可以在任何时候将前台线程修改为后台线程,方式是设置Thread.IsBackground 属性。
3、不管是前台线程还是后台线程,如果线程内出现了异常,都会导致进程的终止。
4、托管线程池中的线程都是后台线程,使用new Thread方式创建的线程默认都是前台线程。
三、创建线程有几种方法,它们之间的区别是什么?
创建线程的方法:
第一种:继承Thread类:
具体步骤如下:
1.定义一个类继承Thread
类;并在自己的类中重写父类的run()
方法
2.创建该类的对象。
3.通过调用start()
方法来启动线程。
代码如下:
class myThread extends Thread{
private String name;
public myThread(String name1){
this.name =name1;
}
public void run(){
for(int i=0;i<10;i++){
System.out.println("线程"+name+"已启动i的值是: "+i);
}
}
}
public class test1 {
public static void main(String[] args){
myThread m1 = new myThread("A");
myThread m2 = new myThread("a");
m1.start();
m2.start();
}
}
第二种:实现Runnable接口
具体步骤如下:
1.自定义一个类,并实现Runnable
接口,并在其中重写run
方法
2.并将自定义的类对象传参至Thread
类的构造函数public Thread(Runnable target)
中。
3.通过调用start()
方法来启动线程。
代码如下:
class myThread implements Runnable{
private String name;
public myThread(String str1){
this.name = str1;
}
@Override
public void run() {
System.out.println("线程"+name+"启动");
for(int i=0;i<10;i++){
System.out.println("线程"+name+"现在的i的值是: "+i);
}
}
}
public class test2_runnable {
public static void main(String[] args){
myThread m3 = new myThread("1号");
myThread m4 = new myThread("2号");
new Thread(m3).start();
new Thread(m4).start();
}
}
二者之间的区别:
实现Runnable
接口的方法
(1)可以实现多个线程资源共享
(2)线程体run()方法所在的类可以从其它类中继承一些有用的属性和方法。
直接继承Thread
类创建对象:
(1)由于java单继承的限制,Thread子类无法再继承其他类。
(2)编写简单,run()方法的当前对象就是线程对象,可直接操作。
四、线程的生命周期有哪些状态,哪些方法可以改变这些状态?
线程的生命周期状态一共有5种:
-
创建 当我们调用
Thread
类的构造方法创建了一个线程对象后,这个线程对象处于创建状态,它有相应的内存空间和其他资源,但是不可运行。 -
可运行 当新建线程对象调用
start
方法时就可以启动线程,,当线程启动时,进入可运行状态,此时线程将进入线程队列排队,等待CPU调度服务。 -
运行 可运行状态的线程被调用并获得处理器资源时,线程进入运行状态 这也是线程进入运行状态的唯一一种方式。
-
阻塞 一个正在运行的线程在某些特殊的情况下,将让出CPU并且暂时中止自己的运行,进入阻塞状态,在运行状态下,如果调用了
sleep()
、suspend()
、wait()
等方法,线程都将进入阻塞状态,阻塞时,线程不能进入排队队列,只有当引起阻塞的原因消除后,线程才可以转入可运行状态。
sleep()
方法代码如下:
class mythread implements Runnable{
String name;
public mythread(String name){
this.name = name;
}
@Override
public void run() {
System.out.println(&