黑马程序员----JAVA基础多线程&同步

本文详细介绍了Android与Java多线程的基本概念、作用、创建方法及同步机制,阐述了多线程在不同场景下的使用时机与特点,并通过实例演示了多线程的创建与同步实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


                                                            ------ android培训java培训、期待与您交流! ----------

一、多线程的概述和用法

1. 多线程的概念

进程:正在执行的程序,它是应用程序运行的一块区域。

线程:进程的执行路径,执行单元。是最小的执行单位。

一个程序在运行的时候,里面的各个功能操作可以同时运行,这些操作也就是执行单元,可以理解为线程,这些线程可以同时运行有多条执行路径这种现象,叫多线程.

2. 多线程的作用

多线程让程序各个功能可以同时进行,效率大大提升.

3. 多线程的用法

两个关键字:Thread(类)  Runnable(接口)  Thread实现了Runnable

两种方式:

  继承Thread 

步骤:
(1)自定义一个类继承Thread类。
(2)继承后重写Thread类中的run方法,把需要实现的代码放入里面去。
(3)通过Thread类或者自定义类创建线程对象。
(4)通过对象调用start方法来启动线程。

:

class A extends Thread

{

A(Srting name)这个方法可以给线程命名,如果要命名就写

{

super(name)

}

public void run

{

//要实现的代码

System.out.println(Thread.currentThread().getName()+this.name+"线程启动.");

}

}

class Test

{

public static void main(Strting[] args)

{

A a =new A("线程1");\

a.start();

//要启动多少个线程,就创建多少个对象.start.

}

}

二 实现Runnable接口 

这种方式与继承最大的区别在于,实现的Runnable里没有start方法,

Thread类里有个方法可以接收Runnable类型对象.

并用用start()方法启动这个对象.里的run方法

步骤:
(1)自定义一个类实现Runnable接口。
(2)实现Runnable接口中的run方法。
(3)通过Thread类创建线程对象,并把自定义类作物参数传递。
(4)通过对象调用start方法。

class B implments Runnable

{

public run{具体代码实现}

}

class Test 

{

public static void main(Strting[] args)

{

B a =new B();

Thread t = new Thread(a);

t.start();

//要启动多少个线程,就创建多少个对象.start.

}

}

4.多线程在什么时候用?

当一个程序里的多个功能关系并不是很紧密,也就是说没有先执行哪个才能执行哪个时,我们可以让里面的各个功能模块独立线程,这样要使用的时候就可以多线程,并同时运行.

5. 多线程的特点?

1,平时多用实现方法创建对程,因为比较接口可以任意实现,没有限制,如果是继承,那么执行一个线程,便要创建一个这个类的对象,那么就又初始化了一次,这样不利于操作同一数据库.除非用静态数据让其与所有对象共享.

2.多线程里各线程执行是随机的,都是在抢夺cpu执行权.

3.线程运行时以run开始,run方法运行完结束.中途如果被其它线程抢夺cpu执行权,那么会进入临时阻塞状态.直到抢回来后,运行完后再销毁.

二、多线程同步

1. 什么是同步?

同步,(关键字是synchrownized,)就是其修饰的一个代码块,或方法,里只能,够有一个线程在运行

2. 同步的用处?

当我们用多线程操作同一数据时,由于线程执行的的不确定性,有可能会出现多个线程重复操作同一数据,比如每次生产一个产品就要出库一个产品,如果线程在生产时暂停了,那么进来一个新线程,同时其又启动了,这时就会产生两个产品,而没有出库.这就产生了安全隐患,如果.

用了同步,那么外面的线程只能等里面的线程执行完后,才能进来,去执行,这就避免了这个情况的产生.

3. 同步的用法

snychronized一般与方法wait() 等待 notify()  唤醒最先等待的那个线程 

notifyAll()唤醒所有 ,这三个方法都在Object类中,Object是所有类的超类.

wait()方法会抛出一个异常,所以要用到try({}catch(){};

格式:

修饰方法:在返回值前加snychronized

修饰代码:snychronized(对象){同步代码}

这个对象可以随便一个,有两个要注意,本类名.class,this 但是如果要和方法上的为同一个,只能用this.

1.5以后的替换用法以:Lock

snychronized体系中,等待唤醒其是一种普及操作,

notify  与  wait(),没有具体联系,是独立的,只与线程偶合性高,唤醒是看哪个线程先等待由线程属性决定


Lock,体系中,wait()  notify()  notifyAll()封装为一个Condition对象,(一个Lock可以对应多个Condition对象,)

那么同时等待与唤醒就有了对应关系,就是说我的等待只能我唤醒,其就具有了从属关系,

每当唤醒与我同一个对象里的等待,与线程等待先后没有关系,那么便可以通过等待与唤醒放置位置的不同,

灵活的控制不同线程的等待与唤醒


使用方法:

1.要先导包,因为其不在lang包中,import java.util.concurrent.locks.*;

2.创建一个把锁:Lock 锁名 = new Lock();

3.创建condition对象 Condition c1 =锁名.newCondition();

Condition c2=锁名.newCondition();.....还可以有很多....

换成三个方法:await()   signal()  signalAll()  

这里要注意,这个方法直接返回一个与当前创建的锁Lock关联的Condition对象,

不然加锁就没意义,只能锁这个锁返回的condition对象,这是Locksynchronized(隐式锁机制)最大的区别.synchronized对所有等待唤醒起作用且如何操作我们不知道

4.使用就是

在要锁的代码最开始加:锁名.lock();

要实现的加锁的代码,[放入等待:里面具体放哪个看自已需要:如比:try{c1.await()}catch(Exception e){}

.......

.......

唤醒:c2.signal();  这个也是自已控制

最后:

finally

{锁名.unlock();}....释放锁一定要执行.

这样我们唤醒只会唤醒自已的等待.

4. 什么时候用?

当需要控制流程,让线程按我们的需求操作共享数据时,这个时候就用同步,也就是线程间需要通信

5. 同步的特点?

注意:notify notifyAll能唤醒的都是同一把锁对象所关联的wait,也就是一把锁synchronized是对应同其一组的wait notifyAll

如果同步synchronized存在于非静态方法上,那么在代码块上表示同一锁就是this,,代表本类对象

如果,存在于静态方法中,那么在代码上表示同一把锁的对象就是本类名.class

类名.class是返回本类的class对象

多线程里的锁,也叫监视器.

被锁同步的方法里或代码内,只能允许一个线程运行.其它的要么冻结,要么阻塞

线程中两个类似功能的wait()sleep(时间),

区别:

1.sleep一定要传时间告诉它要睡眠多久,在这个时间段内它会释放cpu执行权,直到这个时间过去它会自动唤醒然后等待cpu执行权再继续执行,wait可以没有这个时间.

2.sleep可以放于任何位置,wait只能放于同步中.

3.sleep只是释放cpu执行权,而没有释放锁,但是wait锁也放了,cpu执行权也放了.

                                                            ------ android培训java培训、期待与您交流! ----------



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值