线程:进程中负责程序执行的执行单元。一个进程中至少有一个线程。
多线程:解决多任务同时执行的需求,合理使用CPU资源。多线程的运行是根据CPU切换完成,如何切换由CPU决定,因此多线程运行具有不确定性。
线程池:基本思想还是一种对象池的思想,开辟一块内存空间,里面存放了众多(未死亡)的线程,池中线程执行调度由池管理器来处理。当有线程任务时,从池中取一个,执行完成后线程对象归池,这样可以避免反复创建线程对象所带来的性能开销,节省了系统的资源。
进程和线程的区别: 一个进程是一个独立的运行环境,它可以被看作一个程序或者一个应用。而线程是在进程中执行的一个任务。线程是进程的子集,一个进程可以有很多线程,每条线程并行执行不同任务。不同进程使用不同的内存空间,而所有的线程共享一片相同内存空间。别和栈内内存搞混,每个线程都拥有单独的栈内存用来存储本地数据。
创建线程的方式:
1.继承Thread类,扩展线程
class DemoThread extends Thread {
@Override
public void run() {
super.run();
// Perform time-consuming operation...
}
}
DemoThread t = new DemoThread();
t.start();
继承Thread类,覆盖run()方法;
创建线程对象并用start()方法启动线程。
Thread类中的start()和run()方法的区别: 调用start()方法才会启动新线程;如果直接调用Thread的run()方法,它的行为就会和普通的方法一样;为了在新的线程中执行我们的代码,必须使用Thread.start()方法。
2.实现Runnable接口
public class DemoActivity extends BaseActivity implements Runnable {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Thread t = new Thread(this);
t.start();
}
@Override
public void run() {
}
}
用Runnable还是Thread? Java不支持类的多重继承,但允许调用多个接口;所以如果要继承其他类,就调用Runnable接口。 Runnable和Callable有什么不同? Callable的call()方法可以返回值和抛出异常,而Runnable的run()方法没有这些功能。Callable可以返回装载有计算结果的Future对象。
public interface Runnable {
public void run();
}
public interface Callable<V> {
V call() throws Exception;
}
- 多线程的优缺点:
优点:- 适当的提高程序的执行效率(多个线程同时执行)
- 适当的提高了资源利用率(CPU、内存等)
缺点:
- 占用一定的内存空间
- 线程越多CPU的调度开销越大
- 程序的复杂度会上升
synchronized
同步块,多线程访问时同一时刻只能有一个线程能够访问。
wait()、notify()、notifyAll()
final native方法,任何继承java.lang.Object的类都有这三个方法,它们是Java语言提供的实现线程间阻塞和控制进程内调度的底层机制,只能在同步方法或者同步块内调用。
wait()线程进入等待状态,等待它被其他线程通过notify()或者notifyAll()唤醒
notify()随机解除一个在该对象调用wait()方法的线程的阻塞状态
notifyAll()解除所有在该对象调用wait()方法的线程的阻塞状态
调用这三个方法任意一个,当前线程必须是锁的持有者,否则抛出IllegalMonitorStateException异常
wait()与Thread.sleep(long time)的区别
sleep()在指定毫秒数内让当前正在执行的线程休眠,知道interrupt()打断休眠或者sleep()休眠时间到。
wait()使实体所处线程暂停执行,从而使对象进入等待状态,知道内notify()通知或者wait()等待时间到。
wait()方法进入等待状态会释放同步锁,而sleep()不会释放同步锁。
volatile关键字
volatile只有成员变量才能使用它,可以保证下一个读取操作会在前一个写操作之后发生。线程都会直接从内存中读取该变量并且不缓存它,确保了线程读取到的变量是同内存中是一致的。
join()方法:按顺序执行
Thread.yield():线程放弃运行,将CPU的控制权让出。