您的位置:首页 > 其它

多线程

2016-05-16 16:51 197 查看
多线程

16.2.1 进程是处于运行过程中的程序,是系统进行资源分配和调度的独立单位。独立性、动态性、并发性。

线程是进程的组成部分,一个进程可以包含多个线程,一个线程必须有父进程,线程有自己的堆栈、

程序计数器、局部变量,但不拥有系统资源。共享进程资源、独立、并发、抢占。

多线程的好处:线程间共享内存很简单,创建线程比进程代价低。

16.2.2进程的创建

继承Thread类创建线程类:定义Thread的子类,重写run()方法,创建子类实例即线程对象,对象start()方法启动线程。

实现Runnable接口创建线程类:定义Runnable接口的实现类,重写run()方法,创建实现类的实例,并且以此实例作为

Thread的target来创建线程对象,对象start()方法启动线程。(MyThread mtd=new MyThread(); new Thread(mth).start())

16.2.3Callable和Future创建线程

(1)创建Callable的实现类,并实现call()方法,该call方法将作为线程执行体且有返回值

(2)创建Callable实现类的实例,使用FutureTask类包装Callable对象,该FutureTask对象封装了该Callable对象的call()

方法返回值

(3)使用FutureTask对象作为Thread对象的target创建并启动新线程

(4)使用FutureTask对象的get()方法来获得子线程执行结束后的返回值

16.2.4创建线程的三种方式对比

实现Runnable,Callable接口方式创建线程

优势:可以继承其他类,多个线程共享同一个target对象。劣势:编程复杂,使用Thread.currentThread()方法访问当前线程

继承Thread类方式创建线程

优势:编程简单,使用this访问当前线程。劣势:不能继承其他父类

16.3线程的生命周期

sleep()时间到 |--------------->阻塞------------- sleep()

IO方法返回 | | IO阻塞

获得同步锁 | | 等待同步锁

收到通知 | | 等待通知

resume() | V suspend()

新建(new创建一个线程)--->start()--->就绪-------->得到处理资源---------->运行------->stop()------->死亡

<-----yield()或失去处理资源<---- Error或Exception

run()/call()执行完成

16.4线程控制

Thread提供join()方法,让一个线程等待另一个线程完成,阻塞主线程

调用Thread对象的setDaemon(true),方法可将

指定线程设为后台线程然后调用start(),当前所有台线程死亡时,后台线程会自动死亡

线程睡眠,调用Thread的静态方法sleep(),线程进入阻塞状态。

线程让步,Thread的静态方法yield()可以暂停当前执行的线程,转入就绪状态。yield()

让系统的线程调度器,重新调度一次,只有优先级与当前线程相同或者优先级比当前线程高的

处于就绪状态的线程才能获得执行的机会。

改变线程的优先级,Thread类提供setPriority(int i)设定线程优先级,i范围1-10。

16.5.1线程安全

synchronized(obj){ //同步代码块 },obj是同步监视器,执行同步代码块前必须获得对同步监视器的锁定

同步方法synchronize修饰方法,无序显示制定同步监视器,是this,也就是该对象本身

释放同步监视器:执行结束,遇到break、return,未处理的Error或Exception,wait()方法

不会释放同步监视器:Thread.sleep()、Thread.yield()、suspend()方法挂起线程

同步锁(Lock)

16.6.1线程间通信

隐式的同步监视器:

对于使用synchronized修饰的同步方法,该类的默认实例(this)就是同步监视器

对于使用synchronized修饰的同步代码块,同步监视器是synchronized后括号里的对象

线程间通信的方法

wait(),导致当前线程等待,直到其他线程调用该同步监视器的notify()方法或notifyAll()方法来唤醒该线程

调用wait()方法的当前线程会释放对该同步监视器的锁定

notify(),唤醒在此同步监视器上等待的任意单个线程,只有调用wait()方法后,才执行被唤醒的线程

notifyAll(),唤醒此同步监视器上等待的所有线程,只有调用wait()方法后,才执行被唤醒的线程

显式的同步监视器:

使用lock对象保证线程同步。Condition实例被绑定在一个Lock对象上,调用Lock对象的newCondition()方法,

获得Condition对象的实例

await()类似隐式同步监视器的wait(),导致当前线程等待,直到其他线程调用该condition的signal()或signalAll()唤醒该线程。

signal()唤醒在此lock对象上等待的任意单个线程,只有当前线程放弃对该Lock对象的锁定后(调用await方法),才可以执行被唤醒的线程。

signalAll()唤醒在此lock对象上等待的所有线程,只有当前线程放弃对该Lock对象的锁定后(调用await方法),才可以执行被唤醒的线程。

阻塞队列(BlockingQueue)控制线程通信

BlockingQueue是Queue的子接口,提供两个阻塞方法put(E e),take()

实现类:ArrayBlockingQueue,LinkedBlockingQueue,PriorityBlockingQueue,SynchronousQueue,DelayQueue

16.7线程组

Thread类提供如下构造器设置新创建的线程属于哪个线程组

Thread(ThreadGroup group,Runnable target)

Thread(ThreadGroup group,Runnable target,String name)

Thread(ThreadGroup group,String name)

Thread(String name)

Thread(ThreadGroup parent,String name)

16.9线程相关类

ThreadLocal,线程局部变量,为每一个使用该变量的线程都提供一个变量值得副本,使每个线程都可以独立的改变自己的

副本,而不会和其他线程的副本冲突。

ArrayList,LinkedList,HashSet,TreeSet,HashMap,TreeMap等都是线程不安全的。

Collections提供静态方法把这些集合包装成线程安全的集合:synchronizedCollection,sychronizedList,

synchronizedMap,synchronizedSet

eg:HashMap hm=Collections.synchronizedMap(new HashMap());

线程安全的集合分为两类

以Concurrent开头的集合类,ConcurrentHashMap,ConcurrentSkipListMap,ConcurrentSkipListSet,

ConcurrentLinkedQueue和ConcurretLinkedDeque,支持多个线程并发写入访问,并发写入有较好的性能,读取操作不必锁定

以CopyOnWrite开头的集合类,如CopyOnWriteArrayList,CopyOnWriteSet,CopyOnWriteSet底层封装了CopyOnWriteList,因此

两者的实现机制类似,采用复制底层数组的方式实现写操作,性能差,直接读取集合本身,无需加锁与堵塞。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: