JAVA多线程入门
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA多线程入门相关的知识,希望对你有一定的参考价值。
为什么使用多线程
进程之间不能共享内存,但线程之间共享内存很容易
系统创建进程需要为该进程重新分配系统资源,但创建线程代价小得多,因此使用多线程来实现多任务并发比多进程的效率高
JAVA内置了多线程功能支持,而不是单纯的作为底层操作系统的调度方式,从而简化了JAVA的多线程编程
线程的创建
继承
Thread
类(可直接使用this
关键字获得当前对象,多个线程无法共享线程类的实例变量)实现
Runnable
接口(必须使用Thread.currentThread()
方法,多个线程可以共享线程类的实例变量)使用
Callable
和Future
创建线程(call()
方法作为线程执行体,可以有返回值去,可以声明抛出异常)
线程的生命周期
新建(New)--使用
new
关键词新建一个线程就绪(Runnable)--调用
start()
方法运行(Running)--处于就绪状态的线程获得CPU,开始执行
run()
方法体阻塞(Blocked)
线程调用sleep()
方法主动放弃所占用的处理器资源
线程调用了一个阻塞式的IO方法
线程试图获得一个同步监视器,但该监视器被其他线程所持有
线程在等待某个通知
程序调用了线程的suspend()
方法将该线程挂起(容易导致死锁)死亡(Dead)
run()
方法或call()
方法执行完成,线程正常结束
线程抛出一个未捕获的异常
直接调用该线程的stop()
方法来结束该线程(容易导致死锁)
控制线程
join()
方法--当某个程序执行流中调用其他程序的join()
方法时,调用线程被阻塞,直到join()
方法加入的join线程执行完为止setDemon()
方法--将指定线程设置为守护线程sleep()
方法--暂停线程的执行,并进入阻塞状态yield()
方法--暂停线程的执行,并进入就绪状态setPriority()
方法--改变线程的优先级,让优先级高的线程获得更多的执行机会
线程同步
同步代码块(同步监视器为
obj
)synchronized(obj){ ... }
同步方法(同步监视器为
this
)public synchronized void draw{ }
同步锁(Lock)
//定义锁对象private final ReentrantLock lock = new ReentrantLock();//加锁lock.lock();//释放锁lock.unlock();
释放同步监视器的锁定
当前线程的同步方法,同步代码块执行结束
当前线程在同步方法,同步代码块遇到
break
,return
终止了继续执行当前线程在同步方法,同步代码块出现未处理的异常
当前线程执行同步方法,同步代码块时执行了同步监视器对象的
wait()
方法
不释放同步监视器的情况
线程执行同步方法,同步代码块时,程序调用
Thread.sleep()
,Thread.yield()
方法来暂停当前线程的执行线程执行同步代码块时,其他线程调用了该线程的
suspend()
方法将该线程挂起
线程通信
传统的线程通信
对于使用synchronized
修饰的同步方法或代码块,借助Object
类提供的wait()
,notify()
,notifyAll()
方法使用Condition控制线程通信
如果程序显式使用Lock
对象保证同步,则使用Condition
对象的await()
,signal()
,signalAll()
来控制程序的协调运行使用阻塞队列(BlockingQueue)控制线程通信
BlockingQueue
接口:put()
方法尝试把元素放入队列中,入托队列元素已满,则阻塞该线程,take()
方法尝试从队列头部去取出元素,如果队列元素已空,则阻塞该线程
线程池
Executors
工厂类来产生线程池//返回ExecutorService对象的方法newCachedThreadPool() newFixedThreadPool(int nThreads) newSingleThreadExecutor()//返回ScheduleExecutorService线程池的方法newScheduledThreadPool(int corePoolSize) newSingleThreadScheduledExecutor()//生成work stealing池,相当于后台线程池ExecutorService newWorkStealingPool(int parallelism)ExecutorService newWorkStealingPool()
创建
Runnable
或者Callable
实现类的实例调用
ExecutorService
对象的submit()
方法来提交Runnable
或者Callable
实例调用
ExecutorService
对象的shutdown()
方法关闭线程池
ForkJoinPool
--充分利用多核CPU
创建
ForkJoinPool
实例创建有继承了返回值的
RecursiveTask
或无返回值的RecursiveAction
实例调用
ForkJoinPool
的submit(ForkJoinTask task)
或submit(ForkJoinAction action)
方法来执行指定任务线程相关类
ThreadLocal
类
隔离多个线程的数据共享,从根本上避免多个线程之间对共享资源的竞争包装线程不安全的集合类
使用Collections
提供的类方法包装线程安全的集合类
以
Concurrent
开头的集合类以
CopyOnWrite
开头的集合类
以上是关于JAVA多线程入门的主要内容,如果未能解决你的问题,请参考以下文章