【Java中的多线程】(待整理)

1.  多线程(thread、runnable、collable、condition)

1、守护线程(daemon):通过调用void setDaemon(boolean on)方法将自己设置成一个守护线程。thread.setDaemon(true); 当所有的用户线程执行结束后,即使守护线程的run()方法还有未执行语句,也会立刻结束线程。

2、从JDK1.5开始,Java提供了三种方式来创建线程:

继承Thread类创建多线程,重写run()方法作为线程执行体。(不能再继承其他类\每一条线程都是Thread子类的实例共享数据复杂)

实现Runnable接口来创建线程,重写run()方法作为线程执行体。Thread(Runnable in);

实现Callable接口创建线程,重写run()方法作为线程执行体。实现Callable可返回结果,可抛出异常,通过futureTask.get(),方法获取结果,如果没有结果返回,可能会阻塞主线程。

3、线程知识

t.start(); 方法启动一个线程,使其处于就绪状态,得到CPU就执行,而调用run()相当于普通的方法调用。start()方法将“新建”状态下的线程加入“就绪”队列中等待CPU,run()方法属于Thread(),没有内容,需要重写。调用start()会默认调用run()。

**************************

***********************

******此处 缺一个 线程状态转换图

****

(1)对象与线程之间完全解耦or弱解耦(用构造方法创建线程实现联系)

(2)线程同步用sychronized修饰方法

(3)协调同步用wait()等待其他线程完成工作(释放CPU资源)

(4)线程联合,A联合B,A立刻停止,让B先执行

(5)守护线程做一些不重要的工作,一旦所有线程停止工作,守护线程立刻停止

 

4、常用方法:start()、run()、sleep(ms)、isAlive()===>false  true  false

   wait()、sleep()都需要try/catch包裹,或是抛出InterruptedException(检查异常)。

sychronized(同步锁)的目标与wait()方法的目标不一致,会抛出IllegalMonitorSateException,不过InterruptExcprion会先出现。wait()和notify()方法必须采用当前锁调用,必须采用synchronized中的对象。

  wait()、notify()、notifyAll()都是Object类中的final方法,被所有类继承且不允许重写,不可以在非同步方法中出现。

Thread.currentThread() 返回正在实行的线程名称

Thread.interrupt() 用于将当前线程的中断标志位设置为true,如果是wait、sleep、join造成的阻塞,会重新将标志位设置为false,抛出interruptedException异常。如果是IO阻塞会抛出异常,如果是轮询,直接返回。如果是非阻塞的线程,进入阻塞会按照阻塞来处理,非阻塞中断标志位为true的线程遇到wait、join、sleep,直接抛出interruptException,中断标记被清除,设置中断标志位为false。

CyclicBarrier(栅栏)让一组线程等待一个或一些线程,countDownLatch(闭锁)让一组线程等待某个事件。

CopyOnWriterArrayList适合使用在读操作远远大于写操作的场景中,比如缓存。

ReadWriteLock当写操作时,其他线程无法读取或写入数据,而当读操作时,其他线程无法写入数据,但可以读,适用于读取远远大于写入的场景。

Thread.stop()已经弃用。

Thread.suspend()和resume()方法:suspend()使线程进入阻塞状态,并不会自恢复,调用其resume()方法才能使其进入就绪队列。

 

5. 线程安全问题出现的情况: 

1,多个线程使用共用数据时

2,操作共享数据的线程代码  

 

当一个线程在执行操作共享数据的多条代码的过程中,其他线程参与了运算。就会导致线程的安全问题。

解决思路:

就是将多条操作共享数据的线程封装起来,在有线程在执行这些代码的时候,其他线程是不可以参与运算的。

Synchronized :同步代码块:

   Synchronize(对象){

        需要被同步的代码;

    }

同步的好处和弊端:

解决了线程的安全问题。

效率有一点点低。因为同步外的线程都会判断同步锁。

 

同步的使用前提:多线程才使用同步,多线程使用的为同一个锁才使用。

同步代码块:同步代码块的锁是任意的。

同步函数:主线程开启线程后,占用CPU,执行完语句。同步函数使用的锁是当前的对象 this。

 

 

6、同步监视器:

  任何线程进入同步方法,同步代码块之前,必须先获得同步方法,同步代码块对应的同步监视器。对于同步代码块,程序必须显式的为它指定同步监视器。

对于非静态同步方法,该方法的同步监视器是this--调用该方法的对象,

对于静态的同步方法,该方法的同步监视器是类。

Static Synchronized 是一个类的共用监视器,synchronized 是针对拥有同步方法的类 而存在的当前实例的监视器。

1、线程中锁:conditon 线程的阻塞队使用的是 condition互斥锁。

  Condition是在JDK1.5中才出现,Condition的作用是对锁进行更精确的控制,拥有await()、signal()、signalAll()、用来替代传统的Object()的wait()、notify()、notifyAll()。不同的是,Object中的wait(),notify(),notifyAll()方法是和"同步锁"(synchronized关键字)捆绑使用的;而Condition是需要与"互斥锁"/"共享锁"捆绑使用的。调用await()和signal()都必须在lock.lock()和lock.unlock()之间有效。

2、线程调度分为协同调度和抢占性调度,Java使用的是抢占性调度,每个线程由操作系统分配执行时间。协同式调度是指调度线程由线程自身确定。

3、可能会抛出InterruptedException的方法:java.lang.Object类的wait方法,

java.lang.Thread类的sleep方法,

java.lang.Thread的join方法。

Thread.suspend容易造成死锁,已过时,被打断不会抛出InterruptedException()。

4、线程结束的三个原因:

1)run方法执行完成,线程正常结束。

2)线程抛出一个未捕获的Exception或Error

3)调用该线程的stop方法结束线程(容易死锁)

4)thread-clean-pop 抛出一个例外,线程终止,也可以通过其他线程调用thread-cancel()来终止另一个线程。

 

8. Java中的多线程并发:

1. Java并发库的Semaphore可以很轻松完成信号量的控制,Semaphore可以控制某个资源可被同时访问的个数,通过acquire()获取一个许可,如果没有就等待,而release()释放一个许可。

2. CyclicBarrier(栅栏):只有一个方法await()。await()每调用一次,计数便会减少1,并阻塞住当前的进程。当计数减少到0时,阻塞解除,阻塞的线程开始运行。挂起线程,知道所有的线程到达此位置。

3. CountDown(门闩):  某一个线程等待某些线程完成操作。

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值