java中的线程通讯和线程池,Callable任务

线程通讯:
在多线程中,某个线程进入“等待状态”时,需要某个线程来唤醒

等待方法:
wait()//无线等待

wait(long 毫秒)//计时等待

注意,调用wait方法,会自动释放掉锁资源

处于wait状态只能由其他线程唤醒

唤醒方法:
notify();//唤醒处于“等待状态”的任意一个线程,和notify使用相同锁对象的线程

notifyAll();//唤醒处于“等待状态”的所有线程

注意,调用notify(),notifyAll()方法,不会自动释放掉锁资源

使用细节:

等待和唤醒的方法,都要使用锁对象调用需要在同步代码块中使用

等待和唤醒方法都应该使用相同的锁对象调用

消费者,生产者模型:

//共享资源
public class Resource {
    static public int number=0;
}
public class test2 {
    public static void main(String[] args) {
        Object lock=new Object();

        //创建消费者线程
        new Thread(new Runnable() {
            @Override
            public void run() {

                while (true) {
                    synchronized (lock) {
                        if (Resource.number >= 3) {
                            System.out.println("这有足够多的食物");
                            try {
                                lock.wait();//阻塞并释放锁
                            } catch (InterruptedException e) {
                                throw new RuntimeException(e);
                            }
                        } else {
                            Resource.number++;//,一开时number=0,先++再打印
                            System.out.println("[p]:" + Resource.number);
                            lock.notify();//唤醒处于等待状态的线程,且不会释放锁
                            try {
                                Thread.sleep(1000);
                            } catch (InterruptedException e) {
                                throw new RuntimeException(e);
                            }
                        }
                    }
                }

            }
        }).start();
        Runnable task=new Runnable() {
            @Override
            public void run() {
                while (true) {
                    synchronized (lock) {
                        if(Resource.number==0)
                        {
                            System.out.println("这没有足够的资源");
                            try {
                                lock.wait();//阻塞的同时会释放掉锁
                            } catch (InterruptedException e) {
                                throw new RuntimeException(e);
                            }
                        }
                        else {
                            System.out.println("[c]"+Resource.number);//先打印,再--
                            Resource.number--;

                            lock.notify();//唤醒生产者线程,生产者如果没有处于等待,就没事
                            //只能唤醒别的线程
                            try {
                                Thread.sleep(1000);
                            } catch (InterruptedException e) {
                                throw new RuntimeException(e);
                            }

                        }
                    }
                }
            }
        };
        new Thread(task).start();
    }

}

线程池:
如何获得线程池对象:


方式一:使用ExecutorService的实现类ThreadPoolExecutor自创建一个线程池对象 

计算密集型任务:核心线程数:cpu数+1

IO密集型任务:核心线程数:cpu数*2

public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)

参数一:  corePoolSize:指定线程池的核心线程的数量

参数二:maximumPoolSize:指定线程池的最大线程数量

参数三: long keepAliveTime:指定临时线程的存活时间(没有事情干)

参数四:unit:指定临时线程的存活时间单位(分,秒,天)

参数五:workQueue:指定线程池的任务队列

参数六:threadFactory:指定线程池的线程工厂

参数七: handler:指定线程池的任务拒接策略

例如:

ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(3, 5, 8, TimeUnit.MINUTES,
                new ArrayBlockingQueue<>(4), Executors.defaultThreadFactory(),//  // Executors.defaultThreadFactory()获取默认的线程池工厂
                new ThreadPoolExecutor.AbortPolicy());

临时线程什么时候创建:

新任务提交时发现核心线程都在忙,任务对列也满了,并且还可以创建临时线程

什么时候拒绝新任务:
核心线程和临时线程都满了,任务队列也满了 

一个任务类:

public class Task1 implements Runnable{

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+"输出yyyy");
        try{
        Thread.sleep(1000);
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }
    }
}
public class test {
    public static void main(String[] args) {
        //创建一个线程池对象
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(3, 5, 8, TimeUnit.MINUTES,
                new ArrayBlockingQueue<>(4), Executors.defaultThreadFactory(),//  // Executors.defaultThreadFactory()获取默认的线程池工厂
                new ThreadPoolExecutor.AbortPolicy());

        //添加任务
        threadPoolExecutor.execute(new Task1());//线程池会自动创建一个线程,自动处理任务

        threadPoolExecutor.shutdown();//等待线程池所有任务执行完后关闭线程池
        threadPoolExecutor.shutdownNow();//立即关闭线程池
    }
}

方式二:使用Executors工具类

public static ExecutorService newFixedThreadPool(int nThreads)

创建固定线程数量的线程池,如果某个线程因为异常关闭,那么线程池会创建出一个新的线程

public static ExecutorService newSingleThreadExecutor()

创建只有一个线程的线程池, 如果这个线程因为异常关闭,那么线程池会创建出一个新的线程

Callable任务:

 Interface Callable<V>

Callable支持结果返回,Runnable不行

Callable可以抛出异常,Runnable不行

Callable任务处理使用步骤:
1:创建线程池

2:定义Callable任务

3:创建Callable任务,提交任务给线程池

4:获取执行结果

public class test2 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //创建线程池对象
        ExecutorService executorService = Executors.newFixedThreadPool(10);

        //创建一个Callable类型的任务类

        Callable<Integer>callable=new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                int sum=0;
                for(int i=0;i<10;i++)
                {
                    sum+=i;
                }
                return sum;
            }

        };
        //交给线程池处理(submit()方法),并获取返回值
        Future<Integer> submit = executorService.submit(callable);
        System.out.println(submit.get());//通过get方法获取返回值

    }

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

落落落sss

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值