java并发编程总结(1)

入门示例

Thread 和 Runnable

import java.util.Random;

public class MyThreadWithExtends extends Thread {
    String flag;

    public MyThreadWithExtends(String flag){
        this.flag = flag;
    }



    @Override
    public void run() {
        String tname = Thread.currentThread().getName();
        System.out.println(tname+"线程的run方法被调用……");
        Random random = new Random();
        for(int i=0;i<20;i++){
            try {
                Thread.sleep(random.nextInt(10)*100);
                System.out.println(tname+ "...."+ flag);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        Thread thread1 = new MyThreadWithExtends("a");
        Thread thread2 = new MyThreadWithExtends("b");
        thread1.start();
        thread2.start();
        /**
         * 如果是调用thread的run方法,则只是一个普通的方法调用,不会开启新的线程
         */
//      thread1.run();
//      thread2.run();
    }
}
import java.util.Random;

public class MyThreadWithExtends extends Thread {
    String flag;

    public MyThreadWithExtends(String flag){
        this.flag = flag;
    }



    @Override
    public void run() {
        String tname = Thread.currentThread().getName();
        System.out.println(tname+"线程的run方法被调用……");
        Random random = new Random();
        for(int i=0;i<20;i++){
            try {
                Thread.sleep(random.nextInt(10)*100);
                System.out.println(tname+ "...."+ flag);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        Thread thread1 = new MyThreadWithExtends("a");
        Thread thread2 = new MyThreadWithExtends("b");
        thread1.start();
        thread2.start();
        /**
         * 如果是调用thread的run方法,则只是一个普通的方法调用,不会开启新的线程
         */
//      thread1.run();
//      thread2.run();
    }
}

内置锁:synchronized

public class MySynchronized {
    public static void main(String[] args) {
        final MySynchronized mySynchronized = new MySynchronized();
//      final MySynchronized mySynchronized2 = new MySynchronized();
        new Thread("thread1") {
            public void run() {
                synchronized (mySynchronized) {
                try {
                    System.out.println(this.getName()+" start");
                    int i =1/0;   //如果发生异常,jvm会将锁释放
                    Thread.sleep(5000);
                    System.out.println(this.getName()+"醒了");
                    System.out.println(this.getName()+" end");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                }
            }
        }.start();
        new Thread("thread2") {
            public void run() {
                synchronized (mySynchronized) {         //争抢同一把锁时,线程1没释放之前,线程2只能等待
//                  synchronized (mySynchronized2) {    //如果不是一把锁,可以看到两句话同时打印
                    System.out.println(this.getName()+" start");
                    System.out.println(this.getName()+" end");

                }
            }
        }.start();
    }
}

volatile

仅当volatile变量能简化代码的实现以及对同步策略的验证时,才会使用它。volatile的正确使用方式包括:确保它们自身状态的可见性,确保它们引用对象的状态的可见性,以及标识一些重要的程序生命周期事件的发生。

典型用法:检查某个状态标记是否退出循环。

线程池

concurrent包中的五大线程池的创建方式:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;

/**
 * 列出并发包中的各种线程池
 * @author
 *
 */

public class ExecutorDemo {

    public static void main(String[] args) {
        ExecutorService newSingleThreadExecutor = Executors.newSingleThreadExecutor();
        ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();

        int cpuNums = Runtime.getRuntime().availableProcessors();
        System.out.println(cpuNums);
        ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(cpuNums);
        ScheduledExecutorService newScheduledThreadPool = Executors.newScheduledThreadPool(8);


        ScheduledExecutorService newSingleThreadScheduledExecutor = Executors.newSingleThreadScheduledExecutor();
    }
}

ExecutorService 的执行方式有两种:submit与execute,

 execute只能接受Runnable类型的任务submit不管是Runnable还是Callable类型的任务都可以接受,但是Runnable返回值均为void,所以使用Future的get()获得的还是null
 由Callable和Runnable的区别可知:
 1execute没有返回值
 2、submit有返回值,所以需要返回值的时候必须使用submit
1、execute中抛出异常
execute中的是Runnable接口的实现,所以只能使用trycatch来捕获CheckedException,通过实现UncaughtExceptionHande接口处理UncheckedException,即和普通线程的处理方式完全一致。
 2、submit中抛出异常
不管提交的是Runnable还是Callable类型的任务,如果不对返回值Future调用get()方法,都会吃掉异常

callable 跟runnable的区别

  • runnable的run方法不会有任何返回结果,所以主线程无法获得任务线程的返回值
  • callable的call方法可以返回结果,但是主线程在获取时是被阻塞,需要等待任务线程返回才能拿到结果

callable:

import java.util.Random;
import java.util.concurrent.Callable;

public class TaskCallable implements Callable<String>{

    private int s;
    Random r = new Random();
    public TaskCallable(int s){
        this.s = s;
    }

    @Override
    public String call() throws Exception {
        String name = Thread.currentThread().getName();
        long currentTimeMillis = System.currentTimeMillis();
        System.out.println(name+" 启动时间:" + currentTimeMillis/1000);

        int rint = r.nextInt(3);
        try {
            Thread.sleep(rint*1000);
        } catch (InterruptedException e) {

            e.printStackTrace();
        }
        System.out.println(name + " is working..."+s);
        return s+"";
    }

}

runnable:

import java.util.Random;

public class TaskRunnable implements Runnable{
    private int s;

    public TaskRunnable(int s){
        this.s = s;
    }

    Random r = new Random();

    @Override
    public void run() {
        String name = Thread.currentThread().getName();
        long currentTimeMillis = System.currentTimeMillis();
        System.out.println(name+" 启动时间:" + currentTimeMillis/1000);

        int rint = r.nextInt(3);
        try {
            Thread.sleep(rint*1000);
        } catch (InterruptedException e) {

            e.printStackTrace();
        }
        System.out.println(name + " is working..."+s);

    }

}

例子对比:

public static void main(String[] args) {
        //创建一个线程池
        ExecutorService pool = Executors.newCachedThreadPool();
        for(int i = 1; i < 5; i++){
            pool.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.println("thread name: " + Thread.currentThread().getName());
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
        pool.shutdown();
    }
public static void main(String[] args) throws InterruptedException, ExecutionException {
        ExecutorService pool = Executors.newFixedThreadPool(4); 

        for(int i = 0; i < 10; i++){
            Future<String> submit = pool.submit(new Callable<String>(){
                @Override
                public String call() throws Exception {
                    //System.out.println("a");
                    Thread.sleep(5000);
                    return "b--"+Thread.currentThread().getName();
                }              
               });
            //从Future中get结果,这个方法是会被阻塞的,一直要等到线程任务返回结果
            System.out.println(submit.get());
        } 
            pool.shutdown();

    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值