黑马程序员----------多线程
来源:互联网 发布:生成全排列的递归算法 编辑:程序博客网 时间:2024/04/30 22:51
------- android培训、java培训、期待与您交流! ----------
多线程:
进程:正在进行中的程序,
多线程:进程中的程序控制单元
Jvm在启动时,首先先有一个主程序,负责程序的执行,调用的是main函数,主线程执行的代码都在main函数中
当产生垃圾时,收垃圾的过程,不需要主程序来完成,会有一个垃圾回收的线程来完成
多线程的随机性:是由于cpu快速切换线程的原因,cpu切换到哪个程序,哪个程序就会执行
返回当前线程的名称:Thread.currentThread().getName();
开启线程用到了start()方法
开始start()方法:启动了线程,并调用了run()方法
线程状态:开启start
运行 哪个线程获得执行资格,哪个线程执行
冻结 sleep() wait() natify()唤醒
临时阻塞 具备执行资格,无执行权
消亡 stop
创建线程的方式一:继承Thread类
步骤:继承Thread类
覆盖run()方法
创建Thread对象
调用start()方法开启线程
创建线程的方式二:现象Runable接口
步骤:实现Runable接口
覆盖run()方法
创建实例对象 Ticket t=new Ticket();
创建Thread对象 Thread t1=new Thread()
将实例对象与Thread相关联 Thread t1=new Thread(t);
调用start()方法开启线程
好处:实现Runable接口可以避免继承的局限性
多线程的安全问题:当一个线程在执行的过程中,另一条线程却参与进来,并且操作了其中的数据,导致了错误数据的产生。
安全问题产生原因:多条语句执行时,在某一时刻,被某一个线程执行时,还没有执行完,就被另一个线程执行
解决安全问题的原理:
只要将操作共享数据的语句在某一时段让一个线程执行完,在执行过程中,其他线程不能进来执行就可以解决这个问题。
用到了同步代码块synchronized
格式:synchronized(任意对象)
{执行语句}
(任意对象)是为同步代码块的锁,锁的目的是为了被同步的程序只有一个线程在执行,其他线程不能够执行
同步:解决了线程的安全问题,单相对降低了性能
定义同步的前提:必须有两个以上的线程,多个线程必须使用的是同一个锁
同步的第二种表现形式:同步函数
同步函数:定义在函数上的同步,他的锁是this锁
带有static的同步函数,他的锁是类名.class
同步代码块和同步函数大的区别:同步代码块是用的锁是任意对象,同步函数是用的锁是this锁,静态同步使用的锁是类名.class
在一个类中如果只有一个线程,可以使用同步函数,如果有过个线程,必须使用同步代码块,同步代码块比较灵活
延迟加载的单例模式,当出现安全问题时的情况
Public Single{
privateSingle s=null;
privateSingle(){}
publicstatic Single getIntance(){
if(s!=null){
synchronized(Single.class){
if(s!=null){
s=new Single();
}} }return s; }}
同步死锁:同步之间相互嵌套,同步函数中有同步代码块,同步代码块中有同步函数。
线程间的通信:多个线程同时操作一个资源,但是操作的动作去不一样
将资源封装成对象
将线程执行的任务也封装成对象
等待唤醒机制:
wait:将线程冻结,释放了执行权,释放了执行资格,将线程存放到线程池中
notify:唤醒线程池中的一个线程
notify:唤醒线程池中所有的线程
需要注意的是:这些方法必须在同步中定义
方法必须表示所属的锁
wait和sleep的区别:
wait可以指定时间亦可以不指定时间,不指定时间必须有notify或notifyAll唤醒
sleep必须指定时间,时间一到就有冻结状态变成临时阻塞状态
wait会释放执行权,会释放锁
sleep会释放执行权,但不会释放锁
线程的停止:线程停止就是停止其中run方法。方式一:在方法中定义循环标记结束,方式二:如果线程处于冻结状态,不能够读到标记,应使用Thread中interrupt方法将冻结状态强制清除,是线程运行,读到标记,结束线程
Lock接口:
解决线程安全问题使用同步,其终还是锁机制,在1.5版本后,直接将所封装成了对象,线程进入同步就开启了锁,线程结束,退出同步就释放了锁。把这些动作定义在锁中,并封装成了对象。同步时隐形的锁操作,lock是显性的锁操作,他的出现代替了同步
Lock接口中等待唤醒机制是用await(),signal(),signalAll()这些方法来完成的
例子:class Res {
privateString name;
privateint count = 1;
privateLock lock = new ReentrantLock();
privateCondition pro_con = lock.newCondition();
privateCondition con_con = lock.newCondition();
privateboolean falg ;
publicvoid set(String name) {
lock.lock();
try{
while(falg)
try{pro_con.await();} catch(InterruptedException e) {}
this.name= name + "...." + count;
count++;
System.out.println(Thread.currentThread().getName()+ "..生成者.."+ this.name);
falg = true;
con_con.signalAll();
} finally{
lock.unlock();
}
}
public voidget() {
lock.lock();
try{
while(!falg)
try{con_con.await();} catch(InterruptedException e) {}
System.out.println(Thread.currentThread().getName() + "..消费者.."+ this.name);
falg = false;
pro_con.signalAll();
} finally{
lock.unlock();
}
}
}
class Producer implementsRunnable {
privateRes r;
publicProducer(Res r) {
super();
this.r= r;
}
@Override
publicvoid run() {
while(true) {
r.set("面包");
}
}
}
class Consumer implementsRunnable {
privateRes r;
publicConsumer(Res r) {
super();
this.r= r;
}
@Override
publicvoid run() {
while(true) {
r.get();
}
}
}
public classTest3 {
publicstatic void main(String[] args) {
/* 生产者消费者的多线程 */
Res r = new Res();
Producer pro = new Producer(r);
Consumer con = new Consumer(r);
Thread t0 = new Thread(pro);
Thread t1 = new Thread(pro);
Thread t2 = new Thread(con);
Thread t3 = new Thread(con);
t0.start();
t1.start();
t2.start();
t3.start();
}
}
- 黑马程序员 多线程
- 黑马程序员:多线程
- 黑马程序员-java多线程
- 黑马程序员--java 多线程
- 黑马程序员_java多线程
- 黑马程序员-java多线程
- 黑马程序员_多线程
- 黑马程序员 多线程
- 黑马程序员_JAVA多线程
- 黑马程序员—多线程
- 黑马程序员- 多线程
- 黑马程序员_多线程
- 黑马程序员--多线程
- 黑马程序员_多线程
- 黑马程序员--Java多线程
- 黑马程序员---多线程
- 黑马程序员__多线程
- 黑马程序员_多线程
- hdu 5062 单峰数(12321)的个数
- 第三章 3.5.3节练习
- CGIC库的移植
- CGIC库的移植及使用
- Day01 准备工作
- 黑马程序员----------多线程
- SharedPreferences具体使用方法及createPackageContext方法(获取其他应用的共享文件)
- 运营活动需求实现
- JAVA程序设计(02.1)-----个税起征点计算
- Debug文件夹下没有.exe文件
- 黑马程序员----------常用API
- HTML5开发Android App 之 Acceleration
- c#基于udp实现的p2p语音聊天工具
- 一编程基础