本文共 4308 字,大约阅读时间需要 14 分钟。
------- 、、期待与您交流! ----------关于什么是线程,计算机系统的任务发展史,咱这里就不说了。说点比较有意思的东西。
附加:安卓里面的线程:
使用Thread类和使用Runnable接口。在使用Runnable接口时需要建立一个Thread实例。因此,无论是通过Thread类还是Runnable接口建立线程,都必须建立Thread类或它的子类的实例。
(方法一)Thread构造函数:
public Thread( );
public Thread(Runnable target); public Thread(String name); public Thread(Runnable target, String name); public Thread(ThreadGroup group, Runnable target); public Thread(ThreadGroup group, String name); public Thread(ThreadGroup group, Runnable target, String name); public Thread(ThreadGroup group, Runnable target, String name, long stackSize); 创建Thread类的时候,同时也要覆盖run方法,这样才有真正的执行体。 然后,再thread.start();,开启这个线程。
(方法二)使用Runnable接口:
实现这个接口,也就是覆写接口里面的run方法。。实际上,实用实现接口的方法来创建线程,只是用这个实现接口的类去创建Thread类,然后,还是thread.start();。
(方法三)使用ExecutorService、Callable、Future实现有返回结果的多线程
所谓的生命周期,其实可以看待成,任何的一个个体对象,在使用的任何时候都会有一些相应的动作。这个动作,可能是对象本身的,但是,居多,都是外界环境赋予的。编程的时候,我们只要重写这个方法,就可以被使用。
// 开始线程
public void start( ); public void run( );// 挂起和唤醒线程 public void resume( ); // 不建议使用 public void suspend( ); // 不建议使用 publicstatic void sleep(long millis);//区别与class类中的wait方法 参考: publicstatic void sleep(long millis, int nanos); // 终止线程 public void stop( ); // 不建议使用 public void interrupt( ); // 得到线程状态 public boolean isAlive( ); public boolean isInterrupted( ); public static boolean interrupted( ); // join方法 public void join( ) throws InterruptedException;
新建状态(New):当线程对象对创建后,即进入了新建状态,如:Thread t = new MyThread();
就绪状态(Runnable):当调用线程对象的start()方法(t.start();),线程即进入就绪状态。处于就绪状态的线程,只是说明此线程已经做好了准备,随时等待CPU调度执行,并不是说执行了t.start()此线程立即就会执行; 运行状态(Running):当CPU开始调度处于就绪状态的线程时,此时线程才得以真正执行,即进入到运行状态。注:就 绪状态是进入到运行状态的唯一入口,也就是说,线程要想进入运行状态执行,首先必须处于就绪状态中; 阻塞状态(Blocked):处于运行状态中的线程由于某种原因,暂时放弃对CPU的使用权,停止执行,此时进入阻塞状态,直到其进入到就绪状态,才 有机会再次被CPU调用以进入到运行状态。根据阻塞产生的原因不同,阻塞状态又可以分为三种: 1.等待阻塞:运行状态中的线程执行wait()方法,使本线程进入到等待阻塞状态; 2.同步阻塞 -- 线程在获取synchronized同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态; 3.其他阻塞 -- 通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。 死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。
问题原因:当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没执行完,另一个线程参与进来执行,导致共享数据的错误。
一个对象只有一个锁。同步函数锁是this, 静态同步函数锁是class
使用:1. synchronized 方法:通过在方法声明中加入 synchronized关键字来声明 synchronized 方法
2. synchronized 块:通过 synchronized关键字来声明synchronized 块。
关于线程的同步:
1. 在需要同步的方法的方法签名中加入synchronized关键字。
2. 使用synchronized块对需要进行同步的代码段进行同步。
3. 使用JDK 5中提供的java.util.concurrent.lock包中的Lock对象。
4、对于同步的方法或者代码块来说,必须获得对象锁才能够进入同步方法或者代码块进行操作;
5、如果采用method级别的同步,则对象锁即为method所在的对象,如果是静态方法,对象锁即指method所在的Class对象(唯一);
6、对于代码块,对象锁即指synchronized(abc)中的abc;
功能限制,也是为什么有之后同步机制的原因:
它无法中断一个正在等候获得锁的线程,也无法通过投票得到锁,如果不想等下去,也就没法得到锁
java.util.concurrent.lock 中的Lock 框架是锁定的一个抽象,它允许把锁定的实现作为 Java 类,而不是作为语言的特性来实现。这就为Lock 的多种实现留下了空间,各种实现可能有不同的调度算法、性能特性或者锁定语义。
ReentrantLock
类实现了Lock
,它拥有与synchronized
相同的并发性和内存语义,但是添加了类似锁投票、定时锁等候和可中断锁等候的一些特性。此外,它还提供了在激烈争用情况下更佳的性能。(换句话说,当许多线程都想访问共享资源时,JVM 可以花更少的时候来调度线程,把更多时间用在执行线程上。)。
好处:
Lock
和 synchronized 有一点明显的区别 —— lock 必须在 finally 块中释放。
除此之外,与目前的 synchronized 实现相比,争用下的 ReentrantLock
实现更具可伸缩性。(在未来的 JVM 版本中,synchronized 的争用性能很有可能会获得提高。)这意味着当许多线程都在争用同一个锁时,使用 ReentrantLock
的总体开支通常要比 synchronized
少得多。
Condition可以替代传统的线程间通信,用await()替换wait(),用signal()替换notify(),用signalAll()替换notifyAll()。
Condition 将 Object 监视器方法(wait、notify 和 notifyAll)分解成截然不同的对象,以便通过将这些对象与任意 Lock 实现组合使用,为每个对象提供多个等待 set(wait-set)。其中,Lock 替代了synchronized 方法和语句的使用,Condition 替代了 Object 监视器方法的使用。
Condition
实例实质上被绑定到一个锁上。要为特定 实例获得 Condition
实例,请使用其 方法。
附加:
>>很多比较新的技术,都在java.util.concurrent中。针对于并发的线程处理,Java有一个包的类和方法,里面有很多不错的东西。
>>
>>多线程的处理,是一个永远的话题。在代码优化、产品优化的时候,是少不了的。
>>所以,,以后,,还要专门研究这个东西
>>