您的位置:首页 > 职场人生

黑马程序员__Java多线程Thread

2015-12-04 23:55 288 查看
  ------- android培训java培训、期待与您交流!
----------


进程:正在运行的程序,所占有内存空间

程序存储在硬盘,运行时期到了内存中

线程:是一个大程序中的子程序

CPU真正执行的是线程,子程序对于CPU来讲独立执行路径,路径就是线程

1. Java中创建线程

任何都是对象,线程也是对象,对象的描述类

java.lang.Thread类

创建线程的第一种方式,继承Thread类,重写run方法

创建Thread子类对象

调用子类中的方法start()开启线程

void start()

使该线程开始执行;Java 虚拟机调用该线程的 run 方法。

JVM 本身是单线程的程序,还是多线程的程序

一个线程运行我们写的程序,一个线程不定时收取垃圾,JVM帮助你调用Windows中的功能

为什么继承Thread类,入伙,继承Thread类,子类就是一个线程了

为什么重写run方法 Thread中的run方法是空方法,等待子类重写

线程运行的程序是什么,未知的,Java工程师,开放多线程技术的时候

不知道使用Java编程的人员会运行哪些代码

提供一个标准,就是run方法:不管线程运行哪些代码,必须放在run中,线程就运行你run中的代码



2. 线程名字的获取和设置

获取名字,Thread类的方法getName(),返回字符串

线程名字JVM命名的 Thread-0 Thread-1

在Thread子类中,直接使用父类方法getName()获取名字

在不是Thread子类中,获取线程名字

Thread类中,提供了一个静态方法 currentThread()返回值是一个Thread类的对象

方法,返回当前线程对象,既然返回的是对象,方法调用链

String name = Thread.currentThread().getName();

设置线程的名字:

Thread类的方法setName()

Thread类的构造方法

Thread(String name)传递线程名字

Thread子类中,super语句将线程的名字送到父类构造方法

3. 售票的一个案例

利用多线程模拟多窗口一起售票

模拟出了,卡机线程,导致了数据的安全问题

多线程操作同一个数据的时候,出现数据安全问题

如果日后开放的程序,如果实现了线程的数据安全问题,程序员,第一责任人

解决办法:一个线程不执行完毕,其他的线程,不能执行

Java中开放出了同步技术,保证线程的安全性,会阻止其他线程进入

同步代码块

synchronized(任意对象){

线程操作的共享数据

}

4. 创建线程的第二种方式

定义类,实现Runnable接口

重写run方法

class A implements Runnable{

public void run(){

}

}

A类不再是线程类了

直接创建Thread类对象

构造方法Thread(Runnable target) 接受的数据类型是Runnable接口的子类类型

new Thread(new A());

调用Thread类中的start();

两个线程的创建方式的区别

继承Thread类,实现Runnable接口区别

继承,单继承局限性

接口,多现实,避免了单继承的局限性

继承Thread类方式,线程中的数据是对象自己的

实现接口方法,线程中的数据是共享

写多线程程序推荐使用接口方式

5. 同步的原理

synchronized(任意对象){

线程操作的共享数据

}

对象,写在了同步中

专业名词,对象监视器

通俗一点:锁

线程进到同步代码块后,线程获取这把锁,这扇门永久关闭了

当线程出去同步代码块,将锁释放

厕所原理

多线程操作同一个数据,安全问题

如果是单线程,没有数据安全问题

6. 模拟存钱

一张卡,可以多个柜台存钱

余额是0,每个柜台每次存100元

两个柜台,每个存3次

600元,没存一次,查看余额

同步方法,在方法的声明上写同步关键字

线程每次只有一个运行这个方法

当方法中所有代码都是线程操作的的共享数据

同步方法中,锁是什么

确定的是,锁肯定有,锁必须是对象

锁是本类的对象引用this

方法中的同步代码块,锁直接写this

静态方法中的,同步锁是谁

锁是对象!

静态优先于对象,静态中的锁,是本类的class文件对象

Java中,每一个数据类型,JVM都赋予他们一个静态成员变量

class名字,变量的运行结果就是类的class文件对象

静态方法中的锁,就是本类.class字节码文件对象

7. 单例模式

懒汉有安全隐患,多线程并发访问懒汉式的时候

安全问题,同步避免

效率很低,提高懒汉的效率

第一次执行s=null

进同步 创建对象,返回

第二次执行s!=null

没有必要进同步了,直接返回

两次判断,提高效率

8. 死锁案例

在多线程的技术中,两个或者两个以上的线程,同时争夺一个对象监视器

导致程序的假死现象

死锁:出现条件,必须多线程,争夺一个锁,程序中,体现在同步代码块的嵌套效果

死锁的案例,面试过程中经常被考到

9. 线程的通信

两个线程同时对一个资源对象,进行赋值和取值操作

思考,数据安全问题怎么发生的

发生后,怎么解决

数据安全问题:线程的随机性导致程序数据安全隐患

采用了同步技术,依然没有解决

当你发现数据安全问题后,使用了同步技术,还是不能解决

第一点,确定程序是不是多线程在操作共享数据 确定

第二点,使用的同步中的锁,是同一把锁吗,锁不同唯一的

必须将锁变成唯一的对象,才能控制数据安全问题

资源对象,数据的安全性解决了

线程等待和唤醒的方法

没有出现在线程描述类Thread类中

方法定义在了Object类中,为什么这样设计

原因是锁,锁是一个对象,对象是通过类new出来的

锁是哪一个类的对象,无法确定的

但是将方法写在Object类中,所有的类的对象,都具有线程的等待与唤醒方法

wait()方法的使用,将线程永久等待,直到有人唤醒

wait方法必须有锁的支持,wait方法必须写在同步中

锁是唯一的

synchronized(r){

wait();

notify();

}

synchronized(r){

notify()

}

IllegalMonitorStateException

异常,运行时期的异常,抛出该异常,说明wait notify没有锁的支持,没有对象监视器

10. 面试题

wait() sleep() 导致线程等待,两个方法区别在哪里

sleep(毫秒值)自动醒来

wait()永久等待,需要别的线程唤醒

sleep()方法是Thread类的静态方法

wait()方法是Object类的非静态方法

sleep()不需要对象锁

wait()必须有锁的支持

sleep()方法,执行的时候线程不会释放对象锁

wait()方法,执行的时候,线程放弃对象锁,被唤醒的时候,从新获取对象锁,才能运行

多线程总结

1、多线程通信,生产者与消费者

一个产品,分别线程控制,一个控制生产,一个控制消费

生产一个,消费一个,多生产者,多消费者

多个生产与多个消费,全部的唤醒notifyAll()

唤醒以后,数据安全性还是没解决

线程在wait上等待,被唤醒的时候,从Wait这里起来

起来以后,不会再次判断flag是true,还是false,因此数据问题,没哟解决

线程,被唤醒以后,但是判断标记!!

用的是循环的方式,解决线程倒下去后,再起来,必须还要判断标记

但是发现一个问题:

notifyAll()唤醒了全部等待的线程

1个活的,7个等着,全部醒来

浪费资源,能不能唤醒对方的一个线程的

生产者,只唤醒一个消费者

消费者,只唤醒一个生产者

唤醒本方是没有意义,全部唤醒是浪费资源的

Java的JDK1.4版本之前,是做不到了

到了JDK1.5版本后,就可以实现了

提供一套新的多线程的操作方式

synchronized,被替换了

wait(),notify(),notifyAll(),被替换了

JDK1.5的新特性,线程锁定操作

导包 java.util.concurrent.locks

2. JDK1.5的锁 lock接口

Lock接口--synchronized同步

同步是有锁提供

接口中,定义了两个方法 lock() unlock()

要同步线程的时候,使用这两个方法,进行锁操作

Lcok接口的实现类对象ReentrantLock

获取到接口的实现类对象,调用方法,锁操作

新的技术中,JDK提供了一个接口Condition

替换了原有线程方法,wait,notify

将线程进行分组管理

t1-t4 set方法,用锁就是set方法中的锁

t5-t8 get方法,用锁就是get方法中的锁

一个lock接口上,可以实现多个Condition对象

final Condition notFull = lock.newCondition();

final Condition notEmpty = lock.newCondition();

将一个接口Lock,分成两组管理

Condition接口中的三个方法

await() -- wait()

signal() -- notify()

signalAll() -- notifyAll();

3. 线程的停止方式

Thread类中,有一个方法stop(),过时

终止线程的运行,目的结束run方法就行

停止线程的第一种方式,改变变量的值,结束while循环,结束了run方法

处于等待中的线程,怎么停下

4. 守护线程

Thread类中。setDaemon(boolean )传递是true,线程守护线程

如果所有运行的线程,都是守护线程,JVM退出

方法,必须在start开始前调用

Feiq,开启多个聊天窗口的时候,一旦关闭飞秋主程序,聊天窗口也就关闭了

聊天窗口线程,就是飞秋主线程的守护线程,一旦主线程死亡,所有的守护线程就死亡

5. Thread中其他方法,toString() setPriority() join() yield()

toString()继承Object,重写toString()

Thread[Thread-0,5,main]

5 优先级,main 线程组

优先级三个级别,最低,默认,最高

setPriority(int )设置优先级

但是优先级的效果,多核,多线程的CPU上,效果不是很明显了

join() 加入 等待该线程终止

使用join方法的线程,不停止,其他线程运行不了

static yield()

  ------- android培训java培训、期待与您交流!
----------
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: