初级必备:Java版本区别与了解_JavaSE_多线程2

    链接地址:http://www.xx566.com/detail/98.html   

    上一篇:初级必备:Java版本区别与了解_JavaSE_多线程(1)说到,sun公司在Java 5中引入了一系列处理并发和多线程的功能类——Executor框架,其实更准确的说,是提供了java.util.concurrent工具包,在并发编程中使用的工具类,下面我们通过修改一下上一篇的示例来开始今天的学习:

package javase;
 
import java.util.concurrent.locks.ReentrantLock;
 
/**
 * 多线程
 * 
 * @Package javase
 * @ClassName: LockTest
 * @author Realfighter
 * @date 2014-7-8 下午03:40:19
 */
public class LockTest {
 
    private final static ReentrantLock lock = new ReentrantLock();
 
    public static void main(String[] args) {
        new LockThreadByThread().start();
        new Thread(new LockThreadByRunnable()).start();
    }
 
    /**
     * 任一线程持有锁时,都会在10次循环执行后才释放锁
     * 去除lock,输出就比较随意了
     * @Title: testLock
     * @author Realfighter
     * @date 2014-7-9 上午10:56:17
     * @param name
     * @param i
     *            void
     */
    public static void testLock(String name, int i) {
        lock.lock();
        try {
            for (int j = 0; j < 10; j++) {
                System.out.println(name + " print >>>>>>" + i);
            }
        } catch (Exception e) {
        } finally {
            lock.unlock();
        }
    }
 
}
 
class LockThreadByThread extends Thread {
     
    @Override
    public void run() {
        for (int i = 0; i < 50; i++) {
            LockTest.testLock(Thread.currentThread().getName(), i);
        }
    }
}
 
class LockThreadByRunnable implements Runnable {
     
    public void run() {
        for (int i = 0; i < 50; i++) {
            LockTest.testLock(Thread.currentThread().getName(), i);
        }
    }
}

      ReentrantLock是一个可重入的互斥锁,它的功能比使用synchronized关键字的代码块,更强大,在资源竞争不很激烈的情况 下,synchronized的性能要优于ReentrantLock,但是在资源竞争激烈的情况,synchronized的性能会急剧下降,而 ReentrantLock则比较平稳。

      ReentrantLock是Lock接口的一个实现,Lock实现提供了比使用synchronized关键字更广泛的锁操作,它允许更灵活的结构,可 以通过lock()方法获取锁,通过unlock()方法释放锁。那么,我们在获取锁之后又该如何对Thread进行操作呢,这里需要用到 Condition接口(关于Thread与Condition请参阅:初级必备:Java版本区别与了解_JavaSE_线程小结,Condition 将 Object监视器方法(wait、notify 和 notifyAll)分解成截然不同的对象,以便通过将这些对象与任意Lock实现组合使用。Condition实例实质上被绑定到一个锁上,可以通过 lock.newCondition()来为特定lock获取Condition实例。

      锁是控制多个线程对共享资源进行访问的工具。通常,锁提供了对共享资源的独占访问。一次只能有一个线程获得锁,对共享资源的所有访问都需要首先获得锁。不 过,某些锁可能允许对共享资源并发访问,如ReadWriteLock的读取锁,readLock()方法返回用于读取操作的锁,writeLock() 方法返回用于写入操作的锁,写入锁是独占的,而读取锁可以由多个线程同时保持。与互斥锁相比,使用读-写锁所允许的并发性增强将带来更大的性能提高,也能 更好的保证同步。

      java.util.concurrent提供的不只是这些,java.util.concurrent.atomic原子类的小工具包,支持在单个变量 上解除锁的线程安全编程。java.util.concurrent包下提供了多个接口和类,方便我们更好的进行并发编程,这里我们着重关注以下几个:接 口Executor,类Executors,接口Callable,接口Future,接口ExecutorService。Executor接口提供一 种将任务提交与每个任务将如何运行的机制(包括线程使用的细节、调度等)分离开来的方法;ExecutorService接口继承了Executor接 口,定义了一些生命周期的方法,用来操作和管理线程任务;Executors预置了创建线程池的工厂方法和返回Callable的方法;Callable 返回结果或可能抛出异常的任务;Future用于接收ExecutorService调用submit()后返回的结果,通过Future.get()方 法可以得到结果,线程执行完后需要手动调用ExecutorService.shutdown()方法来关闭线程工厂,来看下面的例子:

package javase;
 
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
 
/**
 * 并发编程
 * 
 * @Package javase
 * @ClassName: ExecutorTest
 * @author Realfighter
 * @date 2014-7-9 下午12:35:40
 */
public class ExecutorTest {
 
    public static void main(String[] args) {
        ExecutorTest.testExecutor();
    }
 
    /**
     * // 创建一个可根据需要创建新线程的线程池 
     * Executors.newCachedThreadPool(); 
     * // 创建一个使用单个 worker线程的 
     * Executor Executors.newSingleThreadExecutor(); 
     * // 创建一个可重用线程数为10的线程池 
     * int nThreads = 10;// 可重用线程数为10
     * Executors.newFixedThreadPool(nThreads); 
     * //创建一个线程池,它可安排在给定延迟后运行命令或者定期地执行 
     * int corePoolSize = 10;// 固定保存10个线程在池内
     * Executors.newScheduledThreadPool(corePoolSize);
     * 
     * @Title: testExecutor
     * @author Realfighter
     * @date 2014-7-9 下午01:14:00 void
     */
    public static void testExecutor() {
        ExecutorService pool = Executors.newSingleThreadExecutor();
        Callable c = new Callable() {
            // Callable会默认调用call()方法
            public String call() throws Exception {
                return "hello,relafighter";
            }
        };
        //submit()方法提交一个 Runnable任务用于执行,并返回一个表示该任务的 Future
        Future f = pool.submit(c);
        try {
            //get()方法获取线程执行后的结果
            System.out.println(f.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        //只有手动调用shutdown()才能关闭线程池
        pool.shutdown();
    }
 
}

      总结:线程的并发编程以及java.util.concurrent包的应用是Java编程中的重点和难点,需要不断的积累和应用才能得心应手,关于多线程,当然还远远不止这些,一些队列等有关并发编程的应用,还是需要不间断的学习。

转载于:https://my.oschina.net/realfighter/blog/349701

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值