zoukankan      html  css  js  c++  java
  • java_多线程 (四)

    1.线程通信案例 : 生产者 与 消费者

    //线程通信案例 : 生产者与消费者
    
    /**
     * 注意点 : produceProduct() & customerProduct() 要共享数据所以要改成同步方法
     *          wiat() 要有对应的notify()
     */
    
    //共享数据
    class Clerk{
        private int procudtNum=0;
    
        //生产产品
        public synchronized void produceProduct() {
            if (procudtNum<20){
                procudtNum++;
                System.out.println(Thread.currentThread().getName()+"开始生产产品:"+procudtNum);
                notify();
            }else{
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        //消费产品
        public synchronized void customerProduct() {
            if (procudtNum>0){
                System.out.println(Thread.currentThread().getName()+"开始消费产品:"+procudtNum);
                procudtNum--;
                notify();
            }else{
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    //生产者
    class Producer extends Thread{
        private Clerk clerk;
        public Producer(Clerk clerk){
            this.clerk=clerk;
        }
    
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName()+"开始生产产品..");
            while (true){
                try {
                    sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                clerk.produceProduct();
            }
        }
    }
    //消费者
    class Customer extends Thread{
        private Clerk clerk;
        public Customer(Clerk clerk){
            this.clerk=clerk;
        }
    
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName()+"开始消费产品..");
            while (true){
                try {
                    sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                clerk.customerProduct();
            }
        }
    }
    
    public class ProductTest {
        public static void main(String[] args) {
            Clerk clerk = new Clerk();
    
            Producer p1 = new Producer(clerk);
            p1.setName("生产者1");
            Customer c1 = new Customer(clerk);
            c1.setName("消费者1");
    
            p1.start();
            c1.start();
        }
    }

    2. JDK 5 加入了两种创建线程的新方式

     2.1 实现Callable接口

    //第三种创建线程的方式 : Callable
    
    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.FutureTask;
    
    //1.创建一个实现Callable接口的实现类
    class NewThread implements Callable{
        //2.重写call()方法 , 将此线程具体的代码声明在其中
        @Override
        public Object call() throws Exception {
            int sum=0;
            for (int i = 0; i <= 100; i++) {
                if (i % 2 ==0){
                    System.out.println(i);
                    sum+=i;
                }
            }
            return sum;
        }
    }
    
    public class ThreadNew{
        public static void main(String[] args) {
            //3.创建实现Callable的实现类对象
            NewThread newThread = new NewThread();
            //4.将次实现类作为参数传入FutureTask的构造器中 , 创建FutureFask对象
            FutureTask futureTask = new FutureTask(newThread);
            //5. 启动线程  : 因为FutureFask也是Runnable的实现类 , 所以可以传参
            new Thread(futureTask).start();
            //获取call()的返回值
            try {
                Object i = futureTask.get();
                System.out.println(i);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
    
    }

    2.2 使用线程池

    /*
    创建线程的第四种方式 : 线程池
     */
    
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.ThreadPoolExecutor;
    
    class NumberThread implements Runnable{
        @Override
        public void run() {
            for (int i = 0; i <= 100; i++) {
                if (i % 2 ==0){
                    System.out.println(Thread.currentThread().getName()+":"+i);
                }
            }
        }
    }
    
    public class ThreadPool {
        public static void main(String[] args) {
            //1.创建有固定数量的线程池
            ExecutorService service = Executors.newFixedThreadPool(10);
            //设置线程池的属性 , 因为ExecutorService是一个接口 , 所以需要用接口的实现类来设置 : ThreadPoolExecutor
            ThreadPoolExecutor service1 = (ThreadPoolExecutor) service;
            service1.setCorePoolSize(3);
            //service1.setKeepAliveTime();
    
            //2, 适用于Runnable
            service.execute(new NumberThread());
            //适用于Callable , 可以有返回值
            //service.submit();
    
            //3.关闭线程池
            service.shutdown();
        }
    }
  • 相关阅读:
    (转)要在自己感兴趣的领域成为专家,要经过一万小时训练
    (学习日记)数据结构第一章中life游戏开发的学习记录
    (转)响应式Web设计是大势所趋还是时代的产物
    (学习日记)裘宗燕:C/C++ 语言中的表达式求值
    (转)如果你喜欢编程 给想做程序员的人的7个建议
    NHibernate 中删除数据的几种方法
    如何避免在安装SQL SERVER 2008时,出现Rule “Previous releases of Microsoft Visual Studio 2008″ failed.
    【转】A brief overview of Ncqrs
    爱博图微博图片批量下载小工具
    解释用Q号算出你的年龄的“奥妙”。。。
  • 原文地址:https://www.cnblogs.com/Anonymity-zhang/p/14343635.html
Copyright © 2011-2022 走看看