class PrimeThread extends Thread { long minPrime; PrimeThread(long minPrime) { this.minPrime = minPrime; } public void run() { // compute primes larger than minPrime . . . } } PrimeThread p = new PrimeThread(143); p.start();
编码简单,但存在单继承的局限性,不能继承其他类,不便于扩展。
重写的Run方法不能返回执行结果。
不适合需要返回执行结果的场景。
class PrimeRun implements Runnable { long minPrime; PrimeRun(long minPrime) { this.minPrime = minPrime; } public void run() { // compute primes larger than minPrime . . . } } PrimeRun p = new PrimeRun(143); new Thread(p).start();
线程任务类实现接口,便于扩展,但编程多一层包装对象。
重写的Run方法不能返回执行结果。
不适合需要返回执行结果的场景。
class PrimeCallable implements Callable<V>{ long minPrime; PrimeCallable (long minPrime) { this.minPrime = minPrime; } public V call() throws Exception{ // compute primes larger than minPrime . . . return V; } } Callable<V> call = new PrimeCallable(143); FutureTask<V> target = new FutureTask<T>(call); new Thread(target ).start(); V result = target.get();
通过实现Callable接口再封装成FutureTask对象来创建任务对象。
线程任务类实现接口,扩展性强,可以在线程执行完毕后通过FutureTask返回执行结果。
编码更加更复杂(有点牵强)。
(1)final String
getName()
Returns this thread's name.(获取线程名称)
(2)final void set
Name(String name)
Changes the name of this thread to be equal to the argument
name
.(设置线程名称)
(3)static Thread
currentThread()
Returns a reference to the currently executing thread object.(获取当前线程对象)
没必要为线程设置名称,默认名字即可。
多个线程同事操作同一个共享资源的时候可能出现业务安全问题,称为线程安全问题。
线程同步实现使用加锁,把共享资源上锁,让多线程实现先后依次访问。
synchronized(同步锁对象){操作共享资源的代码}
代码块内容被加锁,代码块执行完毕后自动解锁。
同步锁对象理论上可以是任意唯一对象,但存在每个对象创建都会受与锁对象局限。
实例方法推荐使用this作为锁对象,
静态方法推荐使用字节码(类名.call)作为锁对象。
在方法定义时使用synchronized修饰即可。
算是隐式锁对象,将整个方法作为同步代码块。
同步方法默认使用this和类名.call作为锁对象
使用Lock的实现类ReentrantLock创建。
class X { private final ReentrantLock lock = new ReentrantLock(); // ... public void m() { lock.lock(); // block until condition holds try { // ... method body } finally { lock.unlock(); } } }
比synchronized丰富,更加强大。
通常通过共享一个数据的方式实现,根据数据来决定等待自己或是唤醒别人。
如生产者与消费者模型:生产者线程负责生产数据,消费者线程负责消费生产者生产的数据。
一般要求:生产者线程生产完后唤醒消费者,等待自己,消费者消费完后,唤醒生产者,等待自己。
Object类的等待和唤醒方法:
void wait
()
void notify
()
void notifyall
()
注意:上诉方法应该使用当前同步锁对象进行调用。