`
icarusliu
  • 浏览: 235361 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

java多线程(包含生产者与消费者例子)

    博客分类:
  • java
阅读更多

java多线程
1.任务的run()方法通常总会有某种形式的循环,使得任务一直运行下去直到不再需要,所以要设定跳出循环的条件。通常,它被写成无限循环的形式这就意味着,除非有个条件使用它终止,否则它将永远运行下去。
2.使用Executor:
    java.util.consurrent包中的执行器将为你管理Thread对象,从而简化了并发编程。如:
        ExecutorService exec = Executors.newCachedThreadPool();
        //..= Executors.newFIxedThreadPool(5)是有数量限制的线程集
        //..=Executors.newSingleThreadExecutor()是顺序执行的线程集
        exec.execute(...);
        exec.shutdown();
3.几种方法:
    1.sleep():休眠一段时间
    2.yield():报告自己重要的工作已经完成,可以休息一段时间,让CPU执行其它线程。但是这里不保证会不执行这个线程而去执行其它线程,它只是将本线程的优先级降低来建议运行其它线程。
    3.wait():
    4.join():如在B的run()当中运行A.join():表明B要在A执行完毕或者被中断之后才能继续进行。

4.volatile关键字:
Volatile修饰的成员变量在每次被线程访问时,都强迫从共享内存中重读该成员变量的值。而且,当成员变量发生变化时,强迫线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。
Java语言规范中指出:为了获得最佳速度,允许线程保存共享成员变量的私有拷贝,而且只当线程进入或者离开同步代码块时才与共享成员变量的原始值对比。
这样当多个线程同时与某个对象交互时,就必须要注意到要让线程及时的得到共享成员变量的变化。
而volatile关键字就是提示VM:对于这个成员变量不能保存它的私有拷贝,而应直接与共享成员变量交互。
使用建议:在两个或者更多的线程访问的成员变量上使用volatile。当要访问的变量已在synchronized代码块中,或者为常量时,不必使用。
由于使用volatile屏蔽掉了VM中必要的代码优化,所以在效率上比较低,因此一定在必要时才使用此关键字。


5.守护线程:
    守护线程在没有用户线程可服务时自动离开, 在Java中比较特殊的线程是被称为守护(Daemon)线程的低级别线程。这个线程具有最低的优先级,用于为系统中的其它对象和线程提供服务。将一个用 户线程设置为守护线程的方式是在线程对象创建之前调用线程对象的setDaemon方法。典型的守护线程例子是JVM中的系统资源自动回收线程,我们所熟 悉的Java垃圾回收线程就是一个典型的守护线程,当我们的程序中不再有任何运行中的Thread,程序就不会再产生垃圾,垃圾回收器也就无事可做,所以 当垃圾回收线程是Java虚拟机上仅剩的线程时,Java虚拟机会自动离开。 它始终在低级别的状态中运行,用于实时监控和管理系统中的可回收资源。守护进程(Daemon)是运行在后台的一种特殊进程。它独立于控制终端并且周期性 地执行某种任务或等待处理某些发生的事件。也就是说守护线程不依赖于终端,但是依赖于系统,与系统“同生共死”。那Java的守护线程是什么样子的呢。当 JVM中所有的线程都是守护线程的时候,JVM就可以退出了;如果还有一个或以上的非守护线程则JVM不会退出。

6.捕获异常
    由于线程的本质我,使得不能捕获从线程中逃逸的异常。一旦异常逃出任务的run()方法,它就公向外传播到控制台,除非你采取特殊的步骤捕获这种错误的异 常。以前可以用线程组来完成这一工作,但是现在可以用Executor来解决这个问题,因此不再需要了解有关线程组的任何知识了。

  • join()方法的使用:
public class A{
    public void run(){
       try{
         sleep(1500);
       }catch(InterruptedException ex){}
   }
}

public class B{
    private A a;
    public B(A a){this.a = a;}
   pubic void run(){
       try{
           a.join();
       }catch(InterruptedException ex){}
    }
}

public static void main(String[] args){
    A a = new A();
    B b = new B(a);
    a.start();
    b.start();
   
    a.interrupt();//b在start之后就一直等待,直到执行到a.interrupt()或者a已经执行完毕(
a休眠时间到
}
 

 

  • 生产者与消费者
package com.icarusliu.learn.others;

/**
 * 账户
 * @author liuqi
 *
 */
public class Account {
    private int account;
    
    public Account(){
        this.account = 0;
    }
    
    public int getAccount(){
        return this.account;
    }
    
    public synchronized void deposite(int count){
        this.account += count;
        System.out.println("Deposite " + count);
        notifyAll();//每存一次就唤醒挂起在这个对象上面的线程
    }
    
    public synchronized void withdraw(int count){
        try{
            while(account<count){//如果不够,则进入等待,当有存储进行时,就会唤醒然后继续判断 是否足够
                System.out.println("It's too less!");
                wait();
            }
        }catch(Exception ex){
            ex.printStackTrace();
        }
        
        account -= count;
        System.out.println("Withdraw " + count);
    }
}
 
package com.icarusliu.learn.others;

/**
 * 消费者
 * @author liuqi
 *
 */
public class Consumer extends Thread{
    Account account;

    public Consumer(Account account    ){
        this.account = account;
    }
    
    public void run(){
        account.withdraw(100);
    }
}
 
package com.icarusliu.learn.others;

/**
 * 生产者
 * @author liuqi
 *
 */
public class Producer extends Thread{
    Account account;

    public Producer(Account account    ){
        this.account = account;
    }
    
    public void run(){
        int count = 0;
        while(count++<12){
            account.deposite(10);
            try{
                sleep(10);
            }catch(Exception ex){
                ex.printStackTrace();
            }
        }
    }
}
 
package com.icarusliu.learn.others;

public class ThreadTest {
    Account count = new Account();
    Consumer cThread = new Consumer(count);
    Producer pThread = new Producer(count);
    
    public static void main(String args[]){
        ThreadTest t = new ThreadTest();
        t.cThread.start();
        t.pThread.start();
    }
}

 

 

//例子2,两个线程,一个给j加1,一个减1
package com.icarusliu.learn.thread;

public class ThreadTest {
    private int j;
    
    public ThreadTest(int j){
        this.j= j;
    }
    
    public synchronized void inc(){
        j++;
        j++;
        System.out.println("Add");
    }
    
    public synchronized void dec(){
        j--;
        System.out.println("Delete");
    }
    
    public class Inc extends Thread{
        public void run(){
            inc();
        }
    }
    
    public class Dec extends Thread{
        public void run(){
            dec();
        }
    }
    
    public static void main(String args[]){
        ThreadTest t = new ThreadTest(0);
        int i = 0;
        ThreadGroup g = new ThreadGroup("g");
        for(i=0;i<100;i++){
            Thread incThread = new Thread(g,t.new Inc(),"inc");
            Thread decThread = new Thread(g,t.new Dec(),"dec");
            incThread.start();
            decThread.start();
        }
        while(g.activeCount()!=0);
        System.out.println(t.j);
    }
}


 


总结:
    1.线程中同步代码一般是放在要共享的数据结构当中,而与特定的线程无关。
    2.可以利用线程组来判断是否所运行的线程都已经运行完成。

分享到:
评论

相关推荐

    JAVA实现线程间同步与互斥生产者消费者问题

    本项目通过一个生产者消费者问题的实例,展示了如何在Java中实现线程间的同步与互斥。 生产者消费者问题是经典的并发问题之一,它涉及到两个类型的线程:生产者和消费者。生产者负责生成数据(产品),而消费者则...

    java多线程实现生产者消费者关系

    在实际应用中,我们常常会遇到一种典型的多线程问题——生产者消费者模型。这个模型描述了两种类型的线程:生产者线程负责创建或生产资源,而消费者线程则负责消耗这些资源。在Java中,我们可以利用同步机制来实现...

    Java多线程 生产者-消费者模式

    总之,Java中的生产者-消费者模式是多线程编程中解决数据共享和同步问题的有效手段,通过合理利用`BlockingQueue`等并发工具类,我们可以构建高效、稳定的多线程应用。在开发过程中,了解和掌握这种模式有助于提高...

    java多线程例子-生产者消费者

    在本示例中,“java多线程例子-生产者消费者”旨在展示如何利用多线程来实现生产者和消费者模式。这种模式是并发编程中的经典设计模式,用于协调生产数据和消费数据的两个不同线程。 生产者消费者模式的基本概念是...

    多线程简易实现生产者消费者模式

    生产者消费者模式是一种经典的多线程同步问题解决方案,它源于现实世界中的生产流水线,用于描述生产者(Producer)和消费者(Consumer)之间的协作关系。在这个模式中,生产者负责生成产品并放入仓库,而消费者则从...

    java 多线程之生产者与消费者

    Java多线程中的“生产者与消费者”模式是一种经典的并发编程模型,用于解决资源的生产与消费问题。在这个模式中,生产者线程负责创建或生成数据,而消费者线程则负责处理或消耗这些数据。这种模式充分利用了系统资源...

    【计算机知识】Java多线程之生产者与消费者.doc

    Java多线程中的生产者-消费者问题是并发编程中常见的设计模式。这个模式主要用来解决资源的同步访问问题,确保生产者生产产品时,消费者能够及时消费,反之亦然,而不会造成数据的丢失或者资源的竞争状态。在这个...

    JAVA多线程实现生产者消费者的实例详解

    JAVA多线程实现生产者消费者的实例详解 JAVA多线程实现生产者消费者是指在JAVA编程语言中使用多线程技术来实现生产者消费者模型的实例详解。生产者消费者模型是指在计算机科学中的一种经典模式,描述了生产者和消费...

    模仿线程"生产者与消费者"的例子

    在这个"模仿线程"生产者与消费者"的例子中,我们将深入探讨这个经典的并发设计模式及其背后的原理。 生产者-消费者模式是一种典型的同步问题,用于解决数据生产与消费的异步处理。在这个模型中,生产者线程负责创建...

    生产者-消费者多线程处理

    在我们的例子中,有一个生产者和两个消费者,这意味着数据生成的速度和消费的速度是不同的,需要通过多线程来协调它们之间的交互。 为了实现这个模式,我们需要确保以下条件得到满足: 1. **互斥访问**:当生产者...

    JAVA多线程之生产者消费者模型.docx

    生产者消费者模型是多线程编程中的一个经典设计模式,主要用来解决生产者(生产数据的线程)和消费者(消费数据的线程)之间的同步和通信问题。在这个模型中,生产者生产产品并将其放入一个共享的容器,而消费者则从...

    Java多线程例子分析 消费者的协作程序.doc

    Java多线程是Java编程中一个非常重要的概念,它允许应用程序同时执行多个任务,从而提高程序的效率和响应性。在这个例子中,我们看到的是一个经典的生产者/消费者模型的实现,该模型展示了如何通过线程间的协作来...

    java多线程经典案例

    本案例将深入探讨Java多线程中的关键知识点,包括线程同步、线程通信和线程阻塞。 线程同步是为了防止多个线程同时访问共享资源,导致数据不一致。Java提供了多种同步机制,如synchronized关键字、Lock接口...

    生产者与消费者 java实现

    生产者与消费者问题在计算机科学中是一个经典的多线程同步问题,主要涉及到进程间的通信和资源的共享。在Java中,我们通常通过`wait()`、`notify()`和`notifyAll()`这三个方法,以及`synchronized`关键字来解决这个...

    Java 生产者消费者模式

    在Java编程中,生产者消费者模式是一种典型的多线程协作模型,用于解决系统资源供需不平衡的问题。这个模式的核心思想是将生产数据和消费数据的过程解耦,使得生产者可以独立地生产数据,而消费者可以独立地消费数据...

    java多线程练习demo 基本的线程使用方式 生产者消费者练习 龟兔赛跑练习.zip

    总结来说,"java多线程练习demo" 提供了一个学习和实践Java多线程的平台,通过“生产者消费者”和“龟兔赛跑”等例子,我们可以深入理解Java多线程编程的基本原理和实践技巧。这些知识对于开发高并发、高性能的Java...

    java生产者与消费者问题

    生产者与消费者问题是多线程编程中的一个经典问题,它主要涉及到线程间的协作与同步。在Java中,我们可以利用其内置的并发工具类来解决这个问题。本篇将深入探讨如何使用Java实现生产者和消费者的模型,并通过具体的...

    生产者 消费者 进程 可视化 java

    在Java编程中,"生产者-消费者"模型是一种常见的多线程问题,它涉及到进程间的同步与通信。在这个模型中,生产者线程负责生成数据并放入缓冲区,而消费者线程则负责从缓冲区取出数据进行处理。这里的"车库"例子就是...

    Java多线程管理示例

    下面我们将深入探讨Java多线程的核心概念、同步机制、死锁问题以及wait/notify机制,以"生产者与消费者"的例子来具体阐述。 首先,了解Java中的线程。线程是操作系统分配CPU时间的基本单位,每个线程都有自己的程序...

Global site tag (gtag.js) - Google Analytics