黑马程序员-线程知识总结-No.02

来源:互联网 发布:软件许可合同 编辑:程序博客网 时间:2024/06/04 19:43

---------------------- android培训java培训、期待与您交流! ---------------------- 

1、进程与线程:通常把一个运行中的程序叫做一个进程,程序运行时内部可能有多个顺序执行流,每个顺序执行流就是一个线程。

2、创建线程的方法:

1)直接继承Thread,重写run()方法,创建Thread子类实例,
2)实现Runnable接口,重写run()方法,然后再new Thread(实现Runnable接口的类的对象)创建一个线程,

3、继承Thread类和实现Runnable接口的区别:

1) 如果继承Thread类,子类将增强一些特有功能,但不能再继承其它父类;

2) 如果实现Runnable接口,可以多个线程共享一个资源,适合多线程。

4、线程操作的一些常用方法

Thread.currentThread() :返回当前正在执行的线程对象;

getName() :返回调用该方法的线程名字;

interrupt() :强制让线程恢复到运行中来;

Yield() :暂停该线程;

setPriority() :更改优先级,线程默认优先级是5

join() :用来临时加入线程执行;例:当A线程执行时调用了B线程的join()方法时,调用者(A线程)将被阻塞,知道B线程都执行完,A线程才会被执行。

wait()notify()notifyAll() 这几个方法是Object类里面的,用于线程间通信的,这些方法都使用在synchronized修饰的方法或者代码块中,因为要对持有监视器(锁)的线程操作

5、sleep方法和yield方法的区别:

1)sleep方法暂停当前线程后,会给其它所有线程执行机会,也不管其它线程的优先级;但yield方法只给优先级相同或更高的线程执行机会;

2)sleep方法将调用者线程转入阻塞状态,而yield只是强制当前线程进入就需状态,让系统重新调度一下,因此有可能暂停之后会再次获得资源;

3)sleep方法会抛InterruptedException异常,而yield不会有异常抛出。

6、同步代码块

当多个线程操作同一资源时,为保资源操作的合理正确性,需要用到同步代码块,格式:

synchronized(obj){    //obj为锁

········   //需要被被多个线程操作的代码块,常用于资源处理

}

如果某方法定义的返回类型前用synchronized修饰,这个方法就是同步方法了,同步方法使用的锁是this锁;如果该方法时静态的,使用的锁是该方法所在类的字节码文件对象,即:类名.class

(住:同步代码块的弊端:多个线程需判断锁,消耗资源啊!)

7、同步锁Lock

JDK1.5之后,同步锁使用Lock对象充当,显示地定义同步锁能更好更清晰地操作资源,下面给一个生产者与消费者的例子:

import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;public class ResProConDemo2 {public static void main(String[] args){Resource2 res = new Resource2();new Thread(new Producer2(res)).start();new Thread(new Producer2(res)).start();new Thread(new Consumer2(res)).start();new Thread(new Consumer2(res)).start();}}//资源类class Resource2{private String name;private int count=1;private boolean flag = false;private Lock lock = new ReentrantLock();//将Object类的监视器方法wait()等分解成对象private Condition condition_add = lock.newCondition();private Condition condition_sub = lock.newCondition();//进行添加操作public void add(String name) throws InterruptedException{lock.lock();try {while(flag){condition_add.await();}this.name = name+"--->"+count++;System.out.println(Thread.currentThread().getName()+"=生产了="+this.name);flag = true;condition_sub.signal();}finally{lock.unlock();}}//进行取操作public void sub()throws InterruptedException{lock.lock();try{while(!flag){condition_sub.await();}System.out.println(Thread.currentThread().getName()+"=======消费了==="+this.name);flag = false;condition_add.signal();}finally{lock.unlock();}}}/* * 生产者类 */class Producer2 implements Runnable{private Resource2 res;public Producer2(Resource2 res){this.res = res;}public void run(){while(true){try {res.add("商品");} catch (InterruptedException e) {}}}}/* * 消费者类 */class Consumer2 implements Runnable{private Resource2 res;public Consumer2(Resource2 res){this.res = res;}public void run(){while(true){try {res.sub();} catch (InterruptedException e) {}}}}

使用Lock锁操作的时候需要注意的是每次操作完资源一定要显示的释放锁,即调用unlock()方法。

8、当使用多个锁时,一定要避免发生死锁,一般发生在两个线程相互等待对方释放同步锁而自己并不释放自己锁的情况下。

 ---------------------- android培训java培训、期待与您交流! ----------------------

 详细请查看:http://edu.csdn.net/heima