java学习(五)-并发

java多线程

java的网络编程一般都会离不开多线程,因为用户的连接不可能只有一条,异或是在编写普通的java应用程序的时候 我们也需要同时去处理多个任务,这时候多线程的并发就显得格外重要了。

定义一个java线程有两种方式:

    * 继承Runnable接口。
    * 继承Thread类。

上述两种方式几乎是等价的,都需要你去重写run方法,不过应用接口形式会更灵活一些,因为它允许你去继承另一个不同的类。

线程Thread类有多种API:

    run()       运行线程,实际上就是调用run方法
    start()     启动线程,实际上也是对run的调用,只不过迅速返回了
    interrupt() 中断线程,即退出
    yield()     建议线程调度器把cpu转移给其它线程
    join()      等待其他线程的结束
    setDaemon(boolean) 是否设置成后台线程
    isDaemon()  判断一个线程是否是后台线程

如果要实现多线程,我们当然可以将线程对象放入容器中,因为java中持有对象一般都会首选容器,然后直接对 Thread对象做控制就可以了。java还给我们提供了另外一种方式:线程池(Executor)。

其基本语法为:

    import java.util.concurrent.*;

    ExecutorService exec = Executors.newCachedThreadPool();
    for(int i=0;i<5;i++)
       exec.execute(new Thread());
    exec.shutdown();//中断所有线程

这种调度方法是java推荐的多线程使用方法,它能够处理有返回值的线程,有返回值的线程是继承Callable接口,而 不是Runnable接口,需要改写的部分是call()方法也不是run方法。这种线程必须使用exec.submit()来调用它,此 方法会将返回值存入到Future对象中,Future对象与Callable接口都实现了泛型,想准确获取返回的对象,他们的 泛型指定最好一致。

接下来一个比较重要的问题就是资源的共享问题了,这是一个多线程逃不开的问题。在操作系统中我们一般使用互 斥量(mutex)来控制对共享资源的访问,在java中最常见的方式就是锁,java的加锁有两种方式:

    * synchronized 一般修饰一个方法,表示调用此方法必须先获得锁
    * lock()与unlock() 显式地给一段代码块加锁

上面两种方式,第一种代码量较少,也最常用,但是后一种显式的方法更灵活,因为它能够让你处理代码的异常和 尝试着去获取锁(如果获取锁失败,可以去执行其他的代码,而不是被阻塞)。用第一种方法也可以给一个代码块加 锁,只需要如下来写:

    synchronized(syncObject){
    //some code
    }

其中的syncObject就是加锁的对象(可以是任意的),可以这么理解对方法的加锁,其锁的对象为this。

也许你会问可不可以用一种原子操作来替代同步控制,那我们就来说说原子操作,首先要说一个关键字-volatile (易失型变量),它是指所有对其的更改都会被立即写入内存中,即使你使用了缓存。java并不能像c++那样保持一些 运算的原子性,所以可以这么说java并不能保证任何操作的原子性,任何一个中间状态都有可能被读取。所以java 中增加了一些原子类AtomicInteger,AtomicLong,他们的更新操作都是原子性的,所以在写大规模网络并发编程的 时候,可以使用这些原子类来代替synchronized关键字,能简化不少代码。用作者的话来说就是说到头来还是尽量 使用锁来控制更好一点。

最后我么再来谈谈线程的协作问题,我们直接来看一些方法:

    wait()        挂起线程
    notify()      唤醒某个线程
    notifyAll()   唤醒挂在某个对象上所有线程
    sleep()       使某个线程睡眠一段时间

上面的方法都是在基类Object的一部分,而不是Thread的一部分,前三种方法可以将某个线程挂载(锁)到任何对象上, 如果不显式地指定,那么挂载对象就是this,而有一个限制条件就是必须出现在synchronized包围的代码段(或者 是synchronized方法(this))中。

这一部分只是简单的教你会用多线程,具体的如容器的多线程安全性问题等,有待后续分解。



Previous     Next
zhing /
Published under (CC) BY-NC-SA in categories java  tagged with java