JavaSE基础---多线程
Posted 未知的行走
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaSE基础---多线程相关的知识,希望对你有一定的参考价值。
进程:正在进行的程序。其实就是一个应用程序运行时的内存分配空间。
线程:进程中一个程序执行控制单元,一条执行路径。进程负责的事应用程序的空间的标识,线程负责的事应用程序的执行顺序。
进程和线程的关系:一个进程至少有一个线程在运行,当一个进程中出现多个线程时,就称这个应用程序是多线程应用程序,每个线程在栈区中都有自己的执行空间,自己的方法区、和变量。
JVM启动时,首先有一个主线程,负责程序的执行,调用的是main函数。主线程执行的代码都在main方法中。
当产生垃圾时,收垃圾的动作,是不需要主线程来完成的,应为这样,会出现主线程中的代码执行停止,去运行垃圾会收器代码,效率较低,所以由一个单独的线程来负责垃圾回收。
一、创建多线程程序的两种方法:Thread类和Runnable接口
(一)通过继承Thread类来完成
1、步骤:
(1)定义类继承Thread类;
(2)复写run方法,将要让线程运行的代码都储存到run方法中
(3)通过创建Thread类的子类对象,创建线程对象
(4)调用线程的start方法,开启线程,并自动执行run方法,注意:start()方法会执行两条命令,1、开启线程,2、执行run方法
2、线程的状态:
(1)被创建:start();
(2)运行:具备执行资格,同时具备执行权。
(3)冻结:sleep(time),wait()---notify()唤醒;线程释放执行权,同时释放执行资格;
(4)零时阻塞状态:线程具备cpu的执行资格,没有cpu的执行权
(5)消亡:stop()
(二)通过实现Runnable接口来完成(如果一个类已经继承了其他类,就不能继承Thread类了,Java的单继承局限性。于是只能对该类进行额外的功能扩展)
1、步骤:
(1)定义类实现Runnbale接口;
(2)覆盖接口中的run方法(封装线程要执行的代码);
(3)通过Thread类创建线程对象;
(4)将实现了Runnable接口的子类对象作为实际参数传递给Thread类中的构造函数;(明确线程要执行的代码run方法)
(5)调用Thread对象的start()方法,开启线程,并执行Runnable接口的子类对象中的run()方法。
2、Runnable接口
(1)避免了Java单继承的局限性
(2)Thread类描述时,内部定义的run方法,也来自于Runnable接口
(3)Runnable接口将线程要执行的任务封装成了对象
(三)案例
1、买票
二、多线程的安全问题
当一个线程在执行操作共享数据的多条带没带过程中,其他线程参与了运算,会导致线程安全问题的产生。
1、出现安全问题的两个前提
(1)多个线程在操作共享数据
(2)操作共享数据的线程代码有多条
2、解决方案
只要让某一线程在执行操作共享数据的多条代码时,让其他程序不能执行数据的操作就可以了。即同步
三、同步
1、定义同步的两个前提
(1)必须要有两个或两个以上的线程,才需要同步
(2)多个线程必须保证使用的是同一个锁
2、同步的两种表现形式
(1)同步代码块:
格式:
synchronized(对象)//可以是任意对象,该对象其实就是锁 { //需要被同步的代码 }
(2)同步函数:就是将同步关键字定义在函数上,让函数具备同步性。
同步函数锁使用的锁就是this
当同步函数被static修饰时,静态函数的调用不需要对象,但是静态函数所属类的字节码文件在加载进内存时,这个字节码文件就被封装成了对象。所以此时同步函数所使用的锁就是该类的字节码文件对象。(类名.class)
2、同步代码块和同步函数的区别
(1)同步代码块使用的锁可以是任意对象。
同步函数使用的锁是this,静态同步函数的锁是该类的字节码文件对象。
3、用同步代码块还是同步函数
在一个类中只有一个同步时,可以使用同步函数,但是如果有多个同步,就必须使用同步代码块,来确定不同的锁。所以同步代码块相对灵活一些。
4、使用同步的好处和弊端
(1)好处:解决了线程的安全问题
(2)弊端:相对降低性能,因为判断锁需要消耗资源
以上是关于JavaSE基础---多线程的主要内容,如果未能解决你的问题,请参考以下文章