秋香的博客

在java中,线程有两种实现方式,一种是继承Thread类,一种是实现Runnable接口 对于继承Thread代码实现大概如下:

{() {//线程调用方法}}

调用方式:

(String[] args) {ThreadTest thread1=new ThreadTest();thread1.start();}

对于实现Runnable接口代码实现:

{() {//线程调用方法}}

调用方式:

(String[] args) {RunnableTest thread1=new RunnableTest();Thread t1=new Thread(thread1);t1.start();}

关于选择继承Thread还是实现Runnable接口? 其实Thread中的run方法调用的是Runnable接口的run方法。不知道大家发现没有,Thread和Runnable都实现了run方法,这种操作模式其实就是代理模式。 Thread和Runnable的区别: 如果一个类继承Thread,则不适合资源共享。但是如果实现了Runable接口的话,则很容易的实现资源共享。 Thread代码示范:

{private int count=5;() {while(count>0){System.out.println(“count=”+count);count–;}}(String[] args) {ThreadTest t1=new ThreadTest();ThreadTest t2=new ThreadTest();ThreadTest t3=new ThreadTest();t1.start();t2.start();t3.start();}}

运行结果如下:

Runnable代码如下:

{private int count=5;() {while(count>0){System.out.println(“count=”+count);count–;}}(String[] args) {RunnableTest r1=new RunnableTest();Thread t1=new Thread(r1);Thread t2=new Thread(r1);Thread t3=new Thread(r1);t1.start();t2.start();t3.start();}}

运行结果:

count=1

总结一下: 实现Runnable接口比继承Thread类所具有的优势: 1):适合多个相同的程序代码的线程去处理同一个资源 2):可以避免java中的单继承的限制 3):增加程序的健壮性,代码可以被多个线程共享,代码和数据独立。

请查看我们实现Runnable接口运行结果,5出现多次,我们如果想象成一个卖票系统,5座位的票岂不是卖了多次,这肯定不行的。 这里我们就引进了线程锁,代码如下:

{private int count=5;() {synchronized (this) {while(count>0){System.out.println(“count=”+count);count–;}}}(String[] args) {RunnableTest r1=new RunnableTest();Thread t1=new Thread(r1);Thread t2=new Thread(r1);Thread t3=new Thread(r1);t1.start();t2.start();t3.start();}}

运行结果:

count=2count=1

用Lock实现线程锁,代码如下:

{private int count=5;ReentrantLock lock=new ReentrantLock();() {try {lock.lock();while(count>0){System.out.println(“count=”+count);count–;}} catch (Exception e) {lock.unlock();}}(String[] args) {RunnableTest r1=new RunnableTest();Thread t1=new Thread(r1);Thread t2=new Thread(r1);Thread t3=new Thread(r1);t1.start();t2.start();t3.start();}}

运行结果:

count=2count=1

Lock和synchronized实现的区别: 1.ReentrantLock 拥有Synchronized相同的并发性和内存语义,此外还多了 锁投票,定时锁等候和中断锁等候 线程A和B都要获取对象O的锁定,假设A获取了对象O锁,B将等待A释放对O的锁定, 如果使用 synchronized ,如果A不释放,B将一直等下去,不能被中断 如果 使用ReentrantLock,如果A不释放,可以使B在等待了足够长的时间以后,中断等待,而干别的事情 ReentrantLock获取锁定与三种方式: a) lock(), 如果获取了锁立即返回,如果别的线程持有锁,当前线程则一直处于休眠状态,直到获取锁 b) tryLock(), 如果获取了锁立即返回true,如果别的线程正持有锁,立即返回false; c)tryLock(long timeout,TimeUnit unit), 如果获取了锁定立即返回true,如果别的线程正持有锁,会等待参数给定的时间,在等待的过程中,如果获取了锁定,就返回true,如果等待超时,返回false; d) lockInterruptibly:如果获取了锁定立即返回,如果没有获取锁定,当前线程处于休眠状态,直到或者锁定,或者当前线程被别的线程中断 2.synchronized是在JVM层面上实现的,不但可以通过一些监控工具监控synchronized的锁定,而且在代码执行时出现异常,JVM会自动释放锁定,但是使用Lock则不行,lock是通过代码实现的,要保证锁定一定会被释放,就必须将unLock()放到finally{}中 3.在资源竞争不是很激烈的情况下,Synchronized的性能要优于ReetrantLock,但是在资源竞争很激烈的情况下,Synchronized的性能会下降几十倍,但是ReetrantLock的性能能维持常态;

下面内容 是转载 5.0的多线程任务包对于同步的性能方面有了很大的改进,在原有synchronized关键字的基础上,又增加了ReentrantLock,以及各种Atomic类。了解其性能的优劣程度,有助与我们在特定的情形下做出正确的选择。

总体的结论先摆出来:

快乐不是因为拥有的多而是计较的少

秋香的博客

相关文章:

你感兴趣的文章:

标签云: