Java多线程基础详解
2、创建和使用多线程
3、线程同步
4、同步合集
线程的状态
线程有五种状态:新建、就绪、运行、阻塞或结束。
新建:新建一个线程,线程进入新建状态;
就绪:调用线程的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合集框架中的类不是线程安全的;也就是说,如果它们同时被多个线程访问和更新,它们的内容可能被破坏,可以通过锁定合集或者同步合集来保护合集中的数据
相关文章:
以上就是Java多线程基础详解的详细内容,更多请关注其它相关文章!