黑马程序员——多线程知识总结1
2015-08-01 14:31
561 查看
-------
android培训、java培训、期待与您交流! ----------
多线程算是Java中比较重要的一个部分了,下面把个人觉得的一些重要内容和大家分享下~~
概述
进程:正在执行中的程序
线程:进程中一个负责程序执行的控制单元(执行路径)。
P.S.
1、一个进程中可以有多个执行路径,称之为多线程。
2、一个进程中至少要有一个线程。
多线程的好处:解决了多部分代码同时运行的问题。
多线程的弊端:线程太多,会导致效率的降低。
其实,多个应用程序同时执行都是CPU在做着快速的切换完成的。这个切换是随机的。CPU的切换是需要花
费时间的,从而导致了效率的降低。————>多线程的实质(⊙o⊙)哦。
在单线程程序中,只有上一句代码执行完,下一句代码才有执行的机会。
如何定义一个线程?
创建线程方式一:继承Thread类
1.定义一个类继承Thread类。
2.覆盖Thread类中的run方法。
3.直接创建Thread的子类对象创建线程。
4.调用start方法开启线程并调用线程的任务run方法执行。
run方法中定义的就是线程要运行的任务代码。
P.S.
继承Thread类的类对象调用start方法开启了线程,并执行线程的run方法;
而直接调用run方法,仅仅是对象调用方法,没有新线程开启;
创建线程方式二:实现Runnable接口
1.定义类实现Runnable接口。
2.覆盖接口中的run方法,将线程的任务代码封装到run方法中。
3.通过Thread类创建线程对象,并将Runnable接口的子类对象作为Thread类的构造函数的参数进行传递。
4.调用线程对象的start方法开启线程。
方式二更为常用~~(Java中是单继承,使用方式二避免了Java单继承的局限性。)
其实下面才是重点——多线程的安全性
问题的原因:
当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没有执行完,
另一个线程参与进来执行。导致共享数据的错乱。
解决办法:
对多条操作共享数据的语句,只能让一个线程都执行完。在执行过程中,其他线程不可以参与执行。
在java中,用同步代码块就可以解决这个问题。
同步代码块的格式:
synchronized(对象){
需要被同步的代码;其实就是操作共享数据的语句
}
对象如同锁。持有锁的线程可以在同步中执行。没有持有锁的线程即使获取cpu的执行权,也进不去,因为没有获取锁。
同步的好处:解决了线程的安全问题。
同步的弊端:当线程相当多时,因为每个线程都会去判断同步上的锁,无形中会降低程序的运行效率。
同步的前提:必须有多个线程并使用同一个锁。
当synchronized出现在函数声明上,函数就具备了同步性(同步函数)
利用同步代码块解决安全问题案例:
同步函数和同步代码块的区别:
1.同步函数的锁是固定的this。
2.同步代码块的锁是任意的对象。
静态的同步函数使用的锁是该函数所属字节码文件对象,可以用当前类名.class表示。
总结完各种同步后,提醒各位小心死锁(同步中嵌套同步,但个同步中锁不一样)
上个死锁的例子,小心避免啊
额,先到这里,下回在更
android培训、java培训、期待与您交流! ----------
多线程算是Java中比较重要的一个部分了,下面把个人觉得的一些重要内容和大家分享下~~
概述
进程:正在执行中的程序
线程:进程中一个负责程序执行的控制单元(执行路径)。
P.S.
1、一个进程中可以有多个执行路径,称之为多线程。
2、一个进程中至少要有一个线程。
多线程的好处:解决了多部分代码同时运行的问题。
多线程的弊端:线程太多,会导致效率的降低。
其实,多个应用程序同时执行都是CPU在做着快速的切换完成的。这个切换是随机的。CPU的切换是需要花
费时间的,从而导致了效率的降低。————>多线程的实质(⊙o⊙)哦。
在单线程程序中,只有上一句代码执行完,下一句代码才有执行的机会。
如何定义一个线程?
创建线程方式一:继承Thread类
1.定义一个类继承Thread类。
2.覆盖Thread类中的run方法。
3.直接创建Thread的子类对象创建线程。
4.调用start方法开启线程并调用线程的任务run方法执行。
run方法中定义的就是线程要运行的任务代码。
P.S.
继承Thread类的类对象调用start方法开启了线程,并执行线程的run方法;
而直接调用run方法,仅仅是对象调用方法,没有新线程开启;
创建线程方式二:实现Runnable接口
1.定义类实现Runnable接口。
2.覆盖接口中的run方法,将线程的任务代码封装到run方法中。
3.通过Thread类创建线程对象,并将Runnable接口的子类对象作为Thread类的构造函数的参数进行传递。
4.调用线程对象的start方法开启线程。
方式二更为常用~~(Java中是单继承,使用方式二避免了Java单继承的局限性。)
其实下面才是重点——多线程的安全性
问题的原因:
当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没有执行完,
另一个线程参与进来执行。导致共享数据的错乱。
解决办法:
对多条操作共享数据的语句,只能让一个线程都执行完。在执行过程中,其他线程不可以参与执行。
在java中,用同步代码块就可以解决这个问题。
同步代码块的格式:
synchronized(对象){
需要被同步的代码;其实就是操作共享数据的语句
}
对象如同锁。持有锁的线程可以在同步中执行。没有持有锁的线程即使获取cpu的执行权,也进不去,因为没有获取锁。
同步的好处:解决了线程的安全问题。
同步的弊端:当线程相当多时,因为每个线程都会去判断同步上的锁,无形中会降低程序的运行效率。
同步的前提:必须有多个线程并使用同一个锁。
当synchronized出现在函数声明上,函数就具备了同步性(同步函数)
利用同步代码块解决安全问题案例:
/* 需求: 银行有一个金库。 有两个储户分别存300元,每次存100,存3次。 如何找问题: 1,明确哪些代码是多线程运行代码。 2,明确共享数据。 3,明确多线程运行代码中哪些语句是操作共享数据的。 */ class Bank { private int sum;//金库金额 public void add(int n) { synchronized(this) { sum = sum + n; System.out.println("sum="+sum); } } } class ChuHu implements Runnable { private Bank b = new Bank(); public void run()//储户向金库存钱 { for(int x=0; x<3; x++) { b.add(100); } } } class BankDemo { public static void main(String[] args) { ChuHu c = new ChuHu(); Thread t1 = new Thread(c); Thread t2 = new Thread(c); t1.start(); t2.start(); } }
同步函数和同步代码块的区别:
1.同步函数的锁是固定的this。
2.同步代码块的锁是任意的对象。
静态的同步函数使用的锁是该函数所属字节码文件对象,可以用当前类名.class表示。
总结完各种同步后,提醒各位小心死锁(同步中嵌套同步,但个同步中锁不一样)
上个死锁的例子,小心避免啊
class Test implements Runnable { private boolean flag;//标记位,好让下面出现死锁 Test(boolean flag) { this.flag = flag;//两线程创建时传入不同标记 } public void run() { if(flag)//标记位true的到这来 { while(true) { synchronized(MyLock.locka)//持有locka { System.out.println(Thread.currentThread().getName()+"...if locka "); synchronized(MyLock.lockb)//标记位false的线程持有lockb时,这里就停住进不去了 { System.out.println(Thread.currentThread().getName()+"..if lockb"); } } } } else//标记位false的 { while(true) { synchronized(MyLock.lockb)//持有lockb { System.out.println(Thread.currentThread().getName()+"..else lockb"); synchronized(MyLock.locka)//当上面的持有locka这里就停这了 { System.out.println(Thread.currentThread().getName()+".....else locka"); } } } } } } //封装两个锁方便使用 class MyLock { static Object locka = new Object(); static Object lockb = new Object(); } class DeadLockTest { public static void main(String[] args) { Thread t1 = new Thread(new Test(true)); Thread t2 = new Thread(new Test(false)); t1.start(); t2.start(); } }
额,先到这里,下回在更
相关文章推荐
- 【练习笔记】剑指offer-面试题6 :重建二义树
- 黑马程序员------TreeSet集合框架存储自定义元素之排序Comparable与Comparator
- 黑马程序员-------集合框架之Collection
- 程序员必读书单
- 剑指offer面试题14(Java版):调整数组顺序使奇数位于偶数的前面
- 【练习笔记】剑指offer-面试题5 :从尾到头打印链表
- 黑马程序员——字符串常见操作
- 每个程序员和设计师必做的10项运动
- 黑马程序员——OC类方法
- 【练习笔记】剑指offer-面试题4 :替换空格
- 面试30 求数组中最小的k个数
- 看不惯别人
- 黑马程序员---iOS基础---OC中类创建对象
- 黑马程序员——自学总结(九)正则表达式
- 黑马程序员——OC中方法的声明实现及调用
- 【LeetCode-面试算法经典-Java实现】【061-Rotate List(旋转单链表)】
- 九章算法面试题78 有效回文串
- 硅谷IT企业面试风格漫谈 I - Start Up 面些啥?
- 找工作知识储备(3)---从头说12种排序算法:原理、图解、动画视频演示、代码以及笔试面试题目中的应用
- 黑马程序员----java基础String和stringbuffer总结