【学习日记】java多线程的知识点总结
来源:互联网 发布:php bindto 编辑:程序博客网 时间:2024/05/16 14:30
一、多线程的概念
现在的操作系统是多任务操作系统。多线程是实现多任务的一种方式。
进程是指一个内存中运行的应用程序,每个进程都有自己独立的一块内存空间,一个进程中可以启动多个线程。比如在Windows系统中,一个运行的exe就是一个进程。
线程是指进程中的一个执行流程,一个进程中可以运行多个线程。比如java.exe进程中可以运行很多线程。线程总是属于某个进程,进程中的多个线程共享进程的内存。“同时”执行是人的感觉,在线程之间实际上轮换执行。
—-Java线程:概念与原理
二、多线程的创建与使用
创建线程的两个方法:Thread类和Runnable接口
Thread
创建线程的第一种方式:继承Thread类。
1、定义一个类继承Thread类。作用:创建线程
2、复写Thread类中的run方法。作用:创建线程功能
3、调用线程的start方法。作用:启动线程,调用run方法。若只用run,不用start则无法开启线程
代码如下:
package test; /** * @author wangkun */public class test4 { public static void main(String[] args){ //定义一个类继承Thread类 MyThread mt = new MyThread(); //调用线程的start方法 mt.start(); for (int i = 0; i <60; i++) { System.out.println(Thread.currentThread().getName()+": "+i); } }}class MyThread extends Thread{//复写Thread类中的run方法 public void run(){ for (int i = 0; i <60; i++) { System.out.println(Thread.currentThread().getName()+": "+i); } }}
java虚拟机启动的时候会有一个进程java.exe。该进程中至少一个线程负责java程序的执行,而且这个线程运行的代码存在于main方法中,该线程称之为主线程。
扩展: jvm启动不止一个线程,还有负责垃圾回收机制的线程。
1,为什么多线程运行的每次结果都不同?
因为多个线程都获取cpu的执行权。cpu执行到谁,谁就运行。
明确一点,在某一个时刻,只能有一个程序在运行。(多核除外)cpu在做着快速的切换,以达到看上去是同时运行的效果。我们可以形象把多线程的运行行为在互相抢夺cpu的执行权。这就是多线程的一个特性:随机性。谁抢到谁执行,至于执行多长,cpu说的算。
2,为什么要覆盖run方法呢?
Thread类用于描述线程。
该类就定义了一个功能,用于存储线程要运行的代码。该存储功能就是run方法。也就是说Thread类中的run方法,用于存储线程要运行的代码。
(简而言之:有线程就要用Thread类,用Thread类就要用run方法,用该方法,就要覆盖即重写该方法。)
Runable
创建线程的第二种方式:实现Runable接口
步骤:
1,定义类实现Runnable接口
2,覆盖Runnable接口中的run方法,将线程要运行的代码存放在该run方法中。
3,通过Thread类建立线程对象。
4,将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数。
5,调用Thread类的start方法开启线程,并调用Runnable接口子类的run方法。
代码如下:
package test; /** * @author wangkun */public class test4 { public static void main(String[] args){ //定义类实现Runnable接口 Demo d =new Demo(); //通过Thread类建立线程对象,将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数 Thread t = new Thread(d); //调用线程的start方法 t.start(); for(int x=0;x<60;x++){ System.out.println(Thread.currentThread().getName()+x); } }}class Demo implements Runnable{ //覆盖Runnable接口中的run方法。将线程要运行的代码存放在该run方法中。 public void run(){ for(int x=0;x<60;x++){ System.out.println(Thread.currentThread().getName()+x); } }}
1、为什么要将Runnable接口的子类对象传递给Thread的构造函数?
因为,自定义的run方法所属的对象是Runnable接口的子类对象。所以要让线程去指定指定对象的run方法。就必须明确该run方法所属对象。简单来说,Thread要用run方法,而run方法又是Runnable接口的重写,则Thread应先与Runnable连接,才能使用run方法。
2、实现方式和继承方式有什么区别呢?
两种方式区别:继承Thread:线程代码存放Thread子类run方法中。实现Runnable:线程代码存在接口的子类的run方法中。
实现方式好处:避免了单继承的局限性。
在定义线程时,建立使用实现方式。
三、多线程的安全问题
问题的原因
当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没有执行完,另一个线程参与进来执行。导致共享数据的错误。
解决办法:同步代码块
对多条操作共享数据的语句,只能让一个线程都执行完。在执行过程中,其他线程不可以参与执行。即解决方法为同步。
同步分两种:同步代码块、同步函数(将synchronized当作函数修饰符)。
如果在代码块前加上 synchronized关键字,则此代码块就成为同步代码块。
同步代码块的格式:
//判断锁旗标是否为1,为1则允许进入,为0则不准进入synchronized(同步对象){ 需要被同步的代码}
同步对象如同锁。持有锁的线程可以在同步中执行。没有持有锁的线程即使获取cpu的执行权,也进不去,因为没有获取锁。
1、同步的前提是什么
1,必须要有两个或者两个以上的线程。
2,必须是多个线程使用同一个锁。(即:锁使用同一个对象或者在同一个同步代码块(同步函数)里)
必须保证同步中只能有一个线程在运行。
2、同步的优劣?
好处:解决了多线程的安全问题。
弊端:多个线程需要判断锁,较为消耗资源,
3、同步函数的锁是什么?如果同步函数被静态修饰后,使用的锁是什么呢?
函数需要被对象调用。那么函数都有一个所属对象引用。就是this。所以同步函数使用的锁是this。
如果同步函数被静态修饰后,使用的不是this。因为静态的方法是随着类的加载而执行,此时还没有对象存在,this自然也不存在。静态方法中也不可以定义this。但是静态方法执行时一定有该类对应的字节码文件对象。即:类名.class,该对象的类型是Class,所以静态的同步方法,使用的锁是该方法所在类的字节码文件对象,类名.class。
四、懒汉式和饿汉式
饿汉式:在程序启动或单件模式类被加载的时候,单件模式实例就已经被创建。
懒汉式:当程序第一次访问单件模式实例时才进行创建。
代码如下:
//饿汉式class Single{ //先建立该类对象 private static final Single s = new Single(); private Single(){} public static Single getInstance() { return s; }}//懒汉式class Single{ //先不建立对象 private static Single s = null; private Single(){} public static Single getInstance() { //判断是否为空 if(s==null) { //添加一个同步代码块,提高安全性 synchronized(Single.class) { if(s==null) //--->A; //此时才建立对象 s = new Single(); } } return s; }}
两者的区别在于单例对象建立的时间不同。懒汉式的特点在于实例的延时加载,缺点是多线程访问会出现安全问题,解决办法是加上同步代码块,用双重判断的方式提高效率,同步代码块的锁是该类对应的字节码文件对象
如何选择?:如果单件模式实例在系统中经常会被用到,饿汉式是一个不错的选择。反之如果单件模式在系统中会很少用到或者几乎不会用到,那么懒汉式是一个不错的选择。
- 【学习日记】java多线程的知识点总结
- 【学习日记】java反射的知识点总结
- 【学习日记】有关java的IO的知识点总结
- 【学习日记】java网络编程知识点总结
- java多线程的知识点总结
- Java多线程知识点总结
- java多线程知识点总结
- Java多线程知识点总结
- 【多线程】java多线程知识点总结
- OC基础知识点的总结(全),学习OC的日记
- OC基础知识点的总结(全),学习OC的日记
- 【学习日记】javaIO流的知识点总结(2)
- ThinkPHP学习日记(知识点总结)
- java多线程基础知识点总结
- Java中多线程知识点总结
- JAVA知识点总结15-多线程
- JAVA知识点总结16-多线程
- JAVA多线程、并发知识点总结
- 扩展欧几里得
- 分享pdf转换成html的常用方法
- 使用Inno Setup打包Winform程序
- unity3d动画插件iTween
- android 录像和拍照功能
- 【学习日记】java多线程的知识点总结
- 从服务器中返回的时间字符串(或时间戳)的一些简单处理
- React 生命周期 笔记
- os引导程序boot从扇区拷贝os加载程序loader文件到内存(boot copy kernel to mem in the same method)
- Android 最火的快速开发框架XUtils
- poj2342—树形dp
- ubuntu mysql5.5 修改最大链接数
- 《机器学习》__note1
- 【Leet Code】 75.Sort Colors--medium