Java多线程基础

1、线程的状态

2、创建和使用多线程

3、线程同步

4、同步合集

 

线程的状态

线程有五种状态:新建、就绪、运行、阻塞或结束java源码 springmvc mybatis SSM获取下载地址   

新建:新建一个线程,线程进入新建状态;

就绪:调用线程的start()方法启动线程后,进入就绪状态;

运行:当得到CPU时间,线程从就绪态进入运行态,如果时间片完或者调用yield()方法,运行态的线程可能进入就绪态;

阻塞:调用join()、sleep()、或者wait()方法,或者等待I/O结束,线程处于阻塞态;

完成:当线程执行完run()方法,这个线程就结束。

 

创建和使用多线程

Thread的类图

 

1、继承Thread类来创建新线程

2、实现Runnable接口,重写run()方法

PrintChar实现了Runnable接口,并使用Thread创建线程,由于Thread类实现了Runnable接口,所以可以创建这个类的一个对象,并且调用它的start方法来启动线程

3、线程池

Java提供Executor接口来执行线程池中的任务,提供ExecutorService接口来管理和控制任务。

 

线程同步

 

如果一个共享资源被多个线程同时访问,可能会遭到破坏。例如数据域被先后修改的顺序不同,则最后的值可能不确定。

竞争状态:如果两个或多个任务以一种会引起冲突的方式访问一个公共的资源,称为竞争状态

为了避免竞争状态,应该防止多个线程同时进入程序的某一特定部分,程序中的这部分称为临界区。

1、利用加锁同步

Java可以显式地采用锁和状态来同步线程。一个锁是一个Lock接口的实例,它定义了加锁和释放锁的方法。
RenntrantLock是Lock的一个实现,用于创建相互排斥的锁。可以创建特定公平策略的锁。公平策略值为1真,则确保等待时间最长的线程首先获得锁。为假,则给任意一个等待的线程。

 

2、线程协作

通过调用Lock对象的newCondition()方法而创建的对象,可以使用await(),signal()和signalAll()方法来实现线程之间的相互通信。

当线程调用await()方法时,线程就进入等待状态,等待唤醒的信号。

3、阻塞队列

可以对当前线程产生阻塞,如果一个线程从一个空的阻塞队列中取元素,此时线程会被阻塞知道队列中有了元素,被阻塞的队列会被自动唤醒这样提供了极大的方便性。

几种阻塞队列:
1:ArrayBlockingQueue使用数组来实现阻塞队列,必须指定一个容量或者可选的公平策略来构造
2:LinkedBlockingQueue使用链表来实现阻塞队列。可以创建无边界的或者有边界。
3:PriorityBlockQueue优先队列,按照元素的优先级对元素进行排序。

ArrayBlockingQueue数据域

可以看出存储空间为一个数组,并且有用到锁。

两个重要方法的实现

 

当队列满时等待,不满则进队,此时用锁同步

队列空时等待,不空时出队。

 

阻塞队列的应用

由例子可知,生产者往队列放数,消费者从队列取数,当队列为空则等待,同步已经在队列中实现,无需使用锁和条件。

 

3、信号量

信号量指对共同资源进行访问的对象。在访问资源之前,线程必须从信号量中获取许可。在访问完资源之后,必须把许可返回给信号量。

程序创建了一个具有一个许可的信号量。当一个线程获得许可,其他线程不能访问这个资源,直到之前的线程释放该许可。

 

同步合集

 

Java合集框架中的类不是线程安全的;也就是说,如果它们同时被多个线程访问和更新,它们的内容可能被破坏,可以通过锁定合集或者同步合集来保护合集中的数据

猜你喜欢

转载自qingyu11068.iteye.com/blog/2365683