黑马程序员--多线程(一)
来源:互联网 发布:关于网络鬼片 编辑:程序博客网 时间:2024/05/24 02:37
1.多线程概述
进程:就是一个正在执行中的程序,每一个进程执行都有一个顺序,该顺序是一个执行路径或叫一个控制单元.
线程:就是进程中的一个独立的控制单元,线程在控制着进程的执行,,一个进程中至少有一个线程
创建线程的方式:继承Thread类或实现Runnable接口
继承Thread类:1.定义类继承Thread类
2.复写Thread类中的run方法
3.调用线程的start方法,该方法有两个作用:启动线程,调用run方法
问题:为什么要复写run方法?
答:Thread类用于描述线程,该类就定义了一个功能,用于存储线程要运行的代码,该存储功能就是run方法,也就是说run方法是用来存储线程要运行的代码的
线程状态图
实现Runnable接口: 1.定义类实现Runnable接口
2.覆盖Runnable接口中的run方法
3.通过Thread了建立线程对象
4.将Runnable接口的子类对象传递给Thread的构造函数
5.调用Thread类的start方法开启线程并调用Runnable接口的run方法
问题:为什么要将Runnable接口的子类对象传递给Thread的构造函数?
答:因为自定义的run方法所属的对象是Runnable接口的子类对象,所以要让线程去执行指定对象的run方法,就必须明确该run方法所属的对象.
实现Runnable接口与继承Thread类的区别:继承Thread类线程代码存放于Thread子类run方法中;实现Runnable接口线程代码存在于接口的子类run方法中,而且这种方式避免了单继承的局限性.
2.多线程的安全问题
当多条语句在操作同一个线程共享数据时,一个线程只执行了一部分,还没有执行完,另一个线程就参与了进来,造成了共享数据的错误,这就是数据安全问题.
解决办法:对于执行语句,使用同步代码块使得让一个线程执行完,其他线程才能执行,在执行的过程中,其他线程不可以参与.
同步代码块格式:synchronized(对象){需要被同步的代码;}
同步的前提:必须要有两个或两个以上的线程;必须是多个线程使用同一把锁
同步的优点:解决了多线程的安全问题,缺点:多个线程需要判断锁,较为消耗资源
卖票实例:火车站有四个窗口同时出售100张票
class Ticket implements Runnable {private int ticket = 100;public void run() {while (true) {// 同步代码块,一个线程执行不完,另一个就不能执行synchronized (this) {if (ticket > 0)System.out.println(Thread.currentThread().getName()+ " 出售第 " + ticket--);}}}}class TicketDemo {public static void main(String[] args) {Ticket t = new Ticket();Thread t1 = new Thread(t);// 创建了四个线程,传递的参数是Runnable接口的子类对象Thread t2 = new Thread(t);Thread t3 = new Thread(t);Thread t4 = new Thread(t);t2.start();t3.start();t4.start();t1.start();}}
银行实例:模拟银行存钱,账户余额是0,每次存储100元,开启2个银行窗口,每个窗口存3次,存完之后,账户余额是600元.模拟这个过程
//银行类,存钱的方法class Bank{static int sum = 0;//统计余额变量//银行的存钱的功能public static void add(int money){synchronized(Bank.class){ sum = sum + money;System.out.println("sum="+sum);}}}//储户类,调用银行的存钱功能class Custom implements Runnable{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) {Custom cus = new Custom();Thread t1 = new Thread(cus);//建立两个线程表示两个窗口Thread t2 = new Thread(cus);t1.start();t2.start();}}
注意:静态函数的锁不能使用this,需要用类的字节码文件对象
3.死锁
原理:A线程持有A锁,B线程持有B锁,让A线程去抢夺B锁,B线程去抢夺A锁
class Dead implements Runnable{private boolean b = false;Dead(boolean b){ this.b = b;}public void run(){ while(true) { if(b) { synchronized(Locks.locka) {//0线程,持有了A锁 System.out.println(Thread.currentThread().getName()+" locka...+.. if"); //等待B锁 synchronized(Locks.lockb) { System.out.println(Thread.currentThread().getName()+" lockb...+.. if"); } } } else { synchronized(Locks.lockb) {//1线程就进来了,持有了B锁 System.out.println(Thread.currentThread().getName()+" lockb...+.. else"); synchronized(Locks.locka)//等待获得A锁 { System.out.println(Thread.currentThread().getName()+" locka...+.. else"); } } } }}}//创造锁class Locks{public static Object locka = new Object();public static Object lockb = new Object();}class DeadLock {public static void main(String[] args) {Dead d1 = new Dead(true);Dead d2 = new Dead(false);Thread t1 = new Thread(d1);Thread t2 = new Thread(d2);t1.start();t2.start();}}
4.单例模式的懒汉式同步改进
class Single{private static Single s = null;public static Single getInstance(){if(s==null){ synchronized(Single.class){ if(s==null) { try{Thread.sleep(100);}catch(Exception e){} s = new Single(); } }}return s;}}class SingleThread implements Runnable{public void run(){ for(int x =0 ; x< 20 ; x++){ Single s = Single.getInstance(); System.out.println(s); }}}class SingleTest {public static void main(String[] args) {SingleThread s = new SingleThread(); Thread t1 = new Thread(s); Thread t2 = new Thread(s); Thread t3 = new Thread(s); Thread t4 = new Thread(s);t1.start();t2.start();t3.start();t4.start();}}
学习感悟
- 黑马程序员 多线程(一)
- 黑马程序员--多线程(一)
- 黑马程序员-多线程(一)
- 黑马程序员_JAVA多线程(一)
- 黑马程序员_多线程一
- 黑马程序员 多线程(一)。
- 黑马程序员_多线程(一)
- 黑马程序员-------多线程(一)
- 黑马程序员---多线程(一)
- 黑马程序员——多线程(一)
- 黑马程序员学习日记----多线程(一)
- 黑马程序员--.Net多线程总结(一)
- 黑马程序员 java多线程笔记(一)
- 【黑马程序员】多线程(一) 第十一天
- 黑马程序员——多线程(一)
- 黑马程序员——多线程(一)
- 黑马程序员 JAVA基础 - 多线程(一)
- 黑马程序员——多线程(一)
- Play Framework介绍2--Hello World
- Play Framework介绍3--使用Eclipse开发和调试
- Play源代码分析1—Server启动过程
- 黑马程序员_银行业务调度系统
- 黑马程序员_多线程
- 黑马程序员--多线程(一)
- java classpath
- Codeforces Round #180 (Div. 1)(完全)
- 女神瓦萨比-小黑中国力鉴淘宝给力明星店
- Hibernate中inverse属性-详细介绍
- 关于快速排序(quick sort)及其改进
- 苏一辰高精度乘法
- Git的一些入门知识
- adobe air 和 flash builder 和 flex 和flax 的区别。 越简单直观越好,不要官网的粘贴,看不懂。