一、多线程概论
进程,是一个正在执行中的程序,每个进程都有着独立的内存空间,每个进程中都至少有一个线程,线程是进程内的独立控制单元,控制着进程的执行。
多线程是指一个程序并发执行多个指令流,每个指令流即是一个线程。
cpu在处理多线程时候,其实是快速切换执行,所以在处理多线程共享数据时候会有安全问题。
二、多线程的创建
多线程的创建有两种方法,一种是继承Thread类,一种为实现Runnable接口。
使用继承Thread类方法的代码:
Class ThreadDemo extends Thread{
public static void main(String []args){
ThreadDemo t = new ThreadDemo();
t.start();
}
public void run(){
System.out.println("我是一个新线程");
}
}
使用实现Runnable接口方法的代码:
Class RunnableDemo{
public static void main(String []args){
new Thread( new NewThread() ).start();
}
}
Class NewThread{
public void run(){
System.out.println("我是一个新线程");
}
}
使用继承Thread方法时候,建立他的子类对象时候就已经建立一个新线程;
使用实现Runnable方法,可以继承其余类,有利于代码的健壮性,所以一般使用此类方法。
三. 线程的几种状态
1.新创建状态:线程已被创建但尚未执行(start() 尚未被调用)。
2.运行状态:线程可以执行,虽然不一定正在执行。CPU 时间随时可能被分配给该线程,从而使得它执行。
3.消亡状态:run()结束。或者调用stop()方法。
4.冻结状态:被sleep()或者wait();需要等待sleep时间到或者notify();
5.临时阻塞状态:具备运行资格,但是没有执行权;
四、几种常用方法
setName()
getName()
currentThread()
wait()
notify()
stop()
join()
五、线程同步
多线程在调用共享数据时,一个线程可能只执行了一部分,就切换到了下个线程来执行,导致了错误。
这时候我们就需要使用同步代码块。
synchronized(对象){
需要被同步的代码
}
Synchronized也可以写在方法上,非静态时用的锁是this,静态时用字节码文件对象。
synchronized void aaaa(){
}
Synchronized同步的前提:
1.必须要有两个或者两个以上的线程。
2.必须是多个线程使用同一个锁。
3.必须保证同步中只能有一个线程在运行。
优点:解决了线程的安全问题
弊端:多个线程都需要判断锁,较消耗资源,
sysnchronized同步可能造成死锁,如:
class BrokeLock{
public static void main(String []args){
Lock l = new Lock();
new Thread(l,"一").start();
new Thread(l,"二").start();
}
}
class Lock implements Runnable{
private Object o1 = new Object();
private Object o2 = new Object();
private boolean flag = false;
public void run(){
while(true){
if(flag){
synchronized( o2 ){
synchronized( o1 ){
System.out.println( Thread.currentThread().getName()+"true");
flag = false ;
}
}
}
else{
synchronized( o1 ){
synchronized( o2 ){
System.out.println(Thread.currentThread().getName()+"false");
flag = true ;
}
}
}
}
}
}
jdk1.5以后,可以通过lock(),unlock()方法加锁。unlock()应该放在finally里,这样出异常也能解开锁
class X {
private final Lock lock = new ReentrantLock();
public void m() {
lock.lock();
try {
//方法体
}
finally {
lock.unlock()
}
}
}
六、通讯
多个不同线程调用同一个对象,也会造成造成安全问题,所以需要等待唤醒机制,jdk1.5之前可以通过wait(),notify()方法,wait和notify需要同步锁来控制。java1.5之后可以通过Condition类的await(),signal()方法,在一个锁内可以有多个不同Condition对象await(),signal()。