4

JAVA多线程学习

 2 years ago
source link: http://neoyeelf.github.io/2016/03/10/JAVA%E5%A4%9A%E7%BA%BF%E7%A8%8B%E5%AD%A6%E4%B9%A0/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

本篇文章主要介绍了Java多线程的基本实现,常用方法和高级方法

一. java多线程的基本实现

1.实现的方式:

  • 继承thread类:
class ThreadA extends Thread{
public void run(){
//线程的业务逻辑
ThreadA threadA = new ThreadA();
threadA.start();
  • 实现runnable接口
class RunnableA implements Runnable{
public void run(){
//线程的业务逻辑
RunnableA runnableA = new RunnableA();
new Thread(runnableA).start();

2.thread类常用的方法:

  • 构造方法:thread(),thread(Runnable target)
  • 启动线程:void start()
  • 线程休眠:static void sleep()
  • 当前线程等待join的线程结束:void join()
  • 当前运行线程释放处理器资源:static void yield()
  • 获取当前的运行线程:static Thread currentThread()

3.wait()、notify()和notifyAll()

  • 在使用wait()、notify()和notifyAll()之前,先必须获得该对象的锁,而对应的状态变量也是由该对象锁保护的。
  • wait()是通知当前线程去等待,并且释放锁资源,等待其他线程调用notify()或者notifyAll()方法,恢复线程执行。
  • notify()唤醒一个等待的线程,notifyAll()唤醒所有等待的线程。被唤醒的线程必须等待锁被释放,才能去获取锁从而执行接下来的操作。

二. java多线程的高级方法

1.实现的方式:

  • Future接口+Callable接口
public class Test{
ExecutorService executor = Executors.newCachedThreadPool();
Task task = new Task();
Future<Integer> result = executor.submit(task);
executor.shutdown();
System.out.println("task运行结果"+result.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
class Task implements Callable<Integer>{
@Override
public Integer call() throws Exception {
System.out.println("子线程在进行计算");
Thread.sleep(3000);
int sum = 0;
for(int i=0;i<100;i++)
sum += i;
return sum;
  • FutureTask类+Callable接口
public class Test {
    public static void main(String[] args) {
        //第一种方式
        ExecutorService executor = Executors.newCachedThreadPool();
        Task task = new Task();
        FutureTask<Integer> futureTask = new FutureTask<Integer>(task);
        executor.submit(futureTask);
        executor.shutdown();
        //第二种方式,注意这种方式和第一种方式效果是类似的,只不过一个使用的是ExecutorService,一个使用的是Thread
        /*Task task = new Task();
        FutureTask<Integer> futureTask = new FutureTask<Integer>(task);
        Thread thread = new Thread(futureTask);
        thread.start();*/
            System.out.println("task运行结果"+futureTask.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        System.out.println("所有任务执行完毕");
class Task implements Callable<Integer>{
    @Override
    public Integer call() throws Exception {
        System.out.println("子线程在进行计算");
        Thread.sleep(3000);
        int sum = 0;
        for(int i=0;i<100;i++)
            sum += i;
        return sum;

callable接口一般是配合ExecutorService来使用的,ExecutorService可以通过Executors提供的工厂方法来生成。ExecutorService提供了submit方法,将一个callable任务提交,并且返回一个与callable任务绑定的future对象,来查询执行结果。常用的2个submit方法的实现如下:

<T> Future<T> submit(Callable<T> task);
Future<?> submit(Runnable task);

2.future接口提供的方法

  • 取消任务:boolean cancel(boolean mayInterruptIfRunning)
  • 查询任务是否被成功取消:boolean isCancelled();
  • 查询任务是否完成:boolean isDone();
  • 获取执行结果(会产生阻塞):
    • V get() throws InterruptedException, ExecutionException;
    • V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;

三. java的并发集合

  • hashtable: Hashtable 提供了一种易于使用的、线程安全的、关联的map功能,这当然也是方便的。然而,线程安全性是凭代价换来的―― Hashtable 的所有方法都是同步的。
  • hashmap:它通过提供一个不同步的基类和一个同步的包装器 Collections.synchronizedMap ,解决了线程安全性问题。 通过将基本的功能从线程安全性中分离开来。但hashtable和synchronizedMap只是提供了有条件地线程安全――所有单个的操作都是线程安全的,但是多个操作组成的操作序列却可能导致数据争用,因为在操作序列中控制流取决于前面操作的结果。
  • ConcurrentHashMap:多个读操作几乎总可以并发地执行,同时进行的读和写操作通常也能并发地执行,而同时进行的写操作仍然可以不时地并发进行
  • CopyOnWriteArrayList:在那些遍历操作大大地多于插入或移除操作的并发应用程序中,一般用 CopyOnWriteArrayList 类替代 ArrayList。CopyOnWriteArrayList 含有对一个不可变数组的一个可变的引用,因此,只要保留好那个引用,您就可以获得不可变的线程安全性的好处,而且不用锁 定列表。

其他

  • volatile
  • 多线程退出:设置flag标志位,用volatile修饰符。不能用stop()和interrupt()。

上一篇:API设计和代码结构组织心得

下一篇:solr新手指南


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK