重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
本篇内容主要讲解“什么是java多线程”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“什么是java多线程”吧!
成都创新互联是一家专业提供丰都企业网站建设,专注与网站建设、成都网站制作、H5技术、小程序制作等业务。10年已为丰都众多企业、政府机构等服务。创新互联专业网站设计公司优惠进行中。
线程的五个状态:新建,就绪,运行,阻塞,死亡。 其中就绪和运行两个状态客户互相转换,但运行到阻塞,阻塞到就绪,只能单向转换。
刚new出的线程就是【新建】状态,调用start之后就是就【绪状】态,获取CUP资源并执行后就是【运行】状态,CUP用完/sleep()/调用阻塞IO/被suspend()挂起/正在获取其他线程同步监视器/等待通知等这些行为都有可能让线程从【运行】进入【阻塞】状态。
继承Thread类创建线程
需要写Thread的子类,并重写其中的线程执行体run()方法,通过start()方法来启动线程。
实现Runable接口创建线程类
需要在实现类中重写run()方法,实现类的实例将做为target对象,通过new Thread(target, "thread name").start()启动线程。
使用Callable接口结合Future接口
Callable中的call()方法作为线程执行体,Future的实现类FutureTask(同时实现了Runable)的实例作为target,初始化FutureTask时传入Callable实例,通过new Thread(target,"thread name").start()启动线程。
优劣对比
采用继承Thread类的方法编程相对简单,但无法再继承别的类,且多个线程之间无法共享变量。
采用Runable接口方法可以同时继承其他类,但是无法获取线程的返回值,也不能抛出异常。
采用Callable结合Future的方法虽然编程比较复杂,但是即不受继承限制,又可以获取多线程的返回值,还能抛出异常,因此是最常用的实现多线程的方法。
join()等待别的线程:在某个线程中调用其他线程的join()方法,就会让当前线程进入阻塞,直到被join线程执行完毕。通常会在主线程中调用join()方法,这样可以保证所有子线程都结束了,主线程才结束。
setDaemon():在start()之前调用线程自身的setDatemon()可以设置成后台线程:如果所有前台线程都死亡,后台线程会自动死亡。
sleep(): 通过Thread.sleep() 可以让当前线程进入【睡眠】状态,在睡眠时间到达之前,即使有可用CUP,线程也无法执行,醒来的线程也只能进入就【绪状】态。
yield():通过Thread.yield()可以设置线程的优先级(用数字或者常量),使线程进入【就绪】状态,相当于暂停线程。只有优先级等于或高于当前线程的线程,才有可能获取CUP资源执行,否则当前线程将继续执行。
是为了解决经典的生产者消费者问题(保证事务处理的原子性,例如多个线程向同一个账户存钱取钱,存钱和取钱各自都需要是一个原子操作)。
线程同步的方法,
同步代码块。即将需要同步的代码放在 synchronized(obj){}的大括号中,使得线程要执行同步代码块之前,需要先获取同步监视器(的锁定),执行完之后,需要释放同步监视器。
同步方法。使用synchronized修饰整个方法(不能修饰static方法),同步监视器就是this,当在线程执行体run()或call()中调用这个方法的时候,需要获取到同步监视器的锁定(即同步方法所在类的实例)的线程才能执行同步方法。
注意sleep(), yield(), suspend()方法并不会释放同步监视器。
同步锁。最常用的ReentrantLock锁,是一种更灵活的同步方式,线程需要先加锁,之后加锁成功的线程才能执行代码,之后需要解锁。使用try ... finally 可以保证锁释放。
两个线程互相等待对方(释放同步监视器),就会进入死锁。
例如线程1线锁定A对象,接着睡眠,线程2锁定B对象,也睡眠,然后线程A醒来,如果此时去请求B对象监视器,A将被阻塞,如果B醒来也去请求A监视器,B也将阻塞,并且A和B此时各自持有一个监视器又在互相请求对方监视器,将进入死锁。
线程通信可以保证线程执行的先后顺序。
通常有三种通信方式,
传统的线程通信,使用wait(), nofity(),nitifyAll(),适用于使用同步代码块和同步方法的同步线程中。
使用lock对象返回的condition对象控制线程通信。condition也包含三个方法,await(),signal(),signalAll()。 condition方法使用与使用lock进行线程同步的情况中。
使用阻塞队列(BlockingQueue)控制线程通信。其特征是,当队列满的时候,生产者线程阻塞,此时只有消费者线程能执行代码;当队列空的时候,消费者线程将阻塞,此时只有生产者线程能执行代码。在线程非空且未满的时候,生产者和消费者都可以执行。这种方式更灵活,能通过队列容量控制线程切换。
到此,相信大家对“什么是java多线程”有了更深的了解,不妨来实际操作一番吧!这里是创新互联网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!