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

Java多线程开发五——线程的同步

阅读更多
 
同步方法
同步方法接近于临界区的概念,同一时间只能运行一个线程,一个类中所有的同步方法同一时间内只能有一个线程在一个方法体内执行。例如:
public class Resource {
       public synchronized String get(){
              //..........
              return null;
       }
       public synchronized void put(String str){
              //..........
       }
      
}
当一个线程执行get()时,其他线程既不能执行get(),也不能执行put()。
 
同步块
同步会造成系统性能的下降,为缩小同步的范围,java提供同步块功能。
public class Resource {
       public String get(){
              //..........
              Synchronized(this){
                     //………….
}
              return null;
       }
       public void put(String str){
              //..........
Synchronized(this){
                     //………….
}
 
       }
      
}
同步块与同步方法的意义是一样的,但同步块应用范围更广,使用起来更灵活。同步块类似于锁,可以把synchronized(this)中的this当成一个锁,进入同步块上锁,离开同步块时解锁。使用同一个锁的同步块同一时间内只能有一个同步块被执行。如上面的示例,get中的同步块被执行时,其他的线程既不能进入get同步块,也不能进入put同步块。
如果在Synchronized后面使用不同的对象,则相当于使用多个锁,只有使用相同锁的同步块不能同时执行,使用不同锁得同步块可以同时执行。比如:
private static Object obj1 = new Object();
 
       private static Object obj2 = new Object();
 
       public void test1() {
              System.out.println("test1 enter");
              synchronized (obj1) {
                     for (int i = 0; i < 4; i++) {
                            System.out.println("test1 excute");
                            try {
                                   Thread.sleep(500);
                            } catch (InterruptedException e) {
                                   // TODO Auto-generated catch block
                                   e.printStackTrace();
                            }
                     }
              }
              System.out.println("test1 exit");
       }
 
       public void test2() {
              System.out.println("test2 enter");
              synchronized (obj2) {
                     for (int i = 0; i < 4; i++) {
                            System.out.println("test2 excute");
                            try {
                                   Thread.sleep(400);
                            } catch (InterruptedException e) {
                                   // TODO Auto-generated catch block
                                   e.printStackTrace();
                            }
                     }
              }
              System.out.println("test2 exit");
       }
以上代码执行结果
test1 enter
test1 excute
test2 enter
test2 excute
test2 excute
test1 excute
test2 excute
test1 excute
test2 excute
test1 excute
test2 exit
test1 exit
可以看到test1 test2是交互执行的。也就是说同时不会有两个线程在test1或是在test2中执行,但同时可以一个线程执行test1,一个线程执行test2

等待和通知方法  

JDK1.5之前,Java提供的主要线程同步技术只有等待/通知函数配合同步方法或同步块,suspendresume早就不提倡使用。
Wait()和notify()/notifyAll()是java.lang.Object类的方法,java中任一个类都是Object的子类,换句话说,Java中任一个类都提供wait()notify()/notifyAll()方法。我们来看一下等待通知函数的使用。
我们以一个经典的多线程场景“生产者/消费者”来说明如何使用等待通知函数
 
1、 等待通知函数只能应用在同步方法体或同步块内。也就是说,调用某个对象wait()notify()方法前必须获得这个对象的监视器(monitor
2、 调用某个对象的Wait()方法时,相当于把当前线程放到这个对象的等待区中(可以假想这是对象的一个Collection类型的属性,把线程对象放到这个Collection中),然后挂起这个线程,最后释放这个对象的监视器。Notify()/notifyAll()方法则刚好相反,从对象的等待区中取出线程,恢复,最后释放这个对象的监视器。Notify()notifyAll()的区别是notify从等待区中拿出一个线程并且激活,而notifyAll是从等待区中拿出所有线程并且激活。

使用同步块和等待通知方法的“生产者/消费者”示例

public class SynchronizedSample ...{
    
//模拟资源
    private List<String> resource=new ArrayList<String>();
    
volatile int i=0;
    
boolean exit = false;

    
public SynchronizedSample()...{
        Thread consumer 
= new Thread(new Consumer());
        Thread producer 
= new Thread(new Producer());
        consumer.start();
        producer.start();
    }


    
public void exit()...{
        
this.exit = true;
    }


    
public static void main(String[]args)...{
        SynchronizedSample sample 
= new SynchronizedSample();
        
try ...{
            Thread.currentThread().sleep(
2000);
        }
 catch (InterruptedException e) ...{
            
return;
        }

        sample.exit();
    }


    
public class Consumer implements Runnable ...{

        
public void run() ...{
            
while (!exit) ...{
                
synchronized (resource) ...{
                    
while (resource.isEmpty()) ...{
                        
try ...{
                            
//调用resource的等待方法
                            resource.wait();
                        }
 catch (InterruptedException e) ...{
                            
return;
                        }

                    }

                    System.out.println(
"Consumer take: "+resource.remove(0));
                    
//调用resource的通知方法
                    resource.notifyAll();
                }

            }


        }


    }


    
public class Producer implements Runnable ...{

        
public void run() ...{
            
while (!exit) ...{
                
synchronized (resource) ...{
                    
while (resource.size() >= 10...{
                        
try ...{
                            resource.wait();
                        }
 catch (InterruptedException e) ...{
                            
return;
                        }

                    }

                    String r 
= "Resource"+i++;
                    System.out.println(
"Producer put: "+r);
                    resource.add(r);
                    resource.notifyAll();
                }

            }

        }


    }

}
分享到:
评论

相关推荐

    java多线程教程——一个课件彻底搞清多线程

    Java多线程是Java编程中的核心概念,它允许程序同时执行多个任务,从而提高应用程序的效率和响应性。本教程将深入讲解Java线程的相关知识,包括进程与线程的基本概念、线程的创建和启动、多线程的互斥与同步、线程...

    java多线程案例——未完成

    Java多线程是Java编程中的一个重要领域,它允许程序同时执行多个任务,从而提高系统效率和资源利用率。在这个未完成的案例中,我们可能正在探讨如何在Java中创建和管理线程,以及处理多线程环境下的并发问题。下面是...

    Java多线程的小例子——吃包子

    这个名为"Java多线程的小例子——吃包子"的示例,旨在帮助开发者直观地理解多线程的工作原理。下面我们将深入探讨该示例所涉及的核心知识点。 首先,多线程通常涉及到以下几个关键概念: 1. **线程(Thread)**:...

    Java练手小项目——多线程聊天室.zip

    【Java练手小项目——多线程...通过这个“Java练手小项目——多线程聊天室”,你可以深入了解Java多线程的原理和实践,同时学习到网络编程和并发集合的运用,这对于提升你的Java编程技能和解决实际问题的能力大有裨益。

    java多线程设计

    本知识点将深入探讨Java多线程设计以及如何利用“不可变对象”(immutable objects)来避免多线程环境中的非安全问题。 一、Java多线程基础 1. 线程的创建:Java提供了两种创建线程的方式——继承Thread类和实现...

    java第十章答案JAVA多线程——一篇文章让你彻底征服多线程开发

    ### Java多线程详解 #### 一、线程与进程的概念 在计算机科学中,**进程**是指一个正在运行的应用程序或程序实例,而**线程**则是进程中可并发执行的一部分,是进程内的一个执行流。一个进程可以拥有多个线程,这些...

    JAVA多线程——一篇文章让你彻底征服多线程开发.docx

    ### JAVA多线程详解 #### 一、线程与进程的概念 在计算机科学中,**进程**是指一个正在运行的应用程序或程序实例,而**线程**则是进程中可并发执行的一部分,是进程内的一个执行流。一个进程可以拥有多个线程,这些...

    java 多线程交互简单范例

    这个压缩包中的文件提供了几个关于Java多线程交互的实例,可以帮助我们深入理解如何在并发环境中控制线程的同步,确保数据的一致性和安全性。 首先,让我们讨论一下标题和描述中提到的关键概念——“多线程交互”和...

    Java多线程同步机制在售票系统的实现

    ##### 2.2 Java多线程的特点 1. **多线程的创建**:Java支持通过继承`Thread`类或实现`Runnable`接口两种方式创建多线程。 2. **同步技术**:Java通过`synchronized`关键字提供同步机制,确保多个线程在访问共享...

    JAVA项目——多线程下载代码

    下面我们将深入探讨相关的Java多线程下载知识点。 1. **线程基础**:在Java中,线程是程序执行的最小单元,每个线程负责一部分任务。在多线程下载中,每个线程负责下载文件的一个部分。 2. **Thread类与Runnable...

    java 多线程同步方法的实例

    在Java编程语言中,多...同时,理解并掌握这些同步机制的原理和使用场景,对于提升Java多线程编程的能力至关重要。在实际开发中,要特别注意死锁、活锁和饥饿等问题,避免因线程同步不当而导致的性能下降或程序错误。

    Java多线程编程详解

    ### Java多线程编程详解:深入理解与实践 #### 一、理解多线程机制 多线程,作为现代编程语言的重要特性之一,允许在单一应用程序内并发执行多个任务,从而极大提升了程序的效率和响应速度。在Java中,多线程的...

    Java——多线程编程技术.pdf

    Java多线程编程技术的生命周期包括五个状态:新建态、就绪状态、运行态、挂起态和消亡态。其中,新建态是线程刚刚创建时的状态,线程对象已经被分配了相应的内存空间并被初始化。就绪状态是线程已经启动但是还没有被...

    java多线程学习资料

    ### Java多线程学习资料知识点解析 #### 一、引言 Java作为一种广泛使用的编程语言,在并发编程领域具有独特的优势。多线程是Java中实现并发处理的核心技术之一,能够显著提升程序的性能和响应性。本文将深入探讨...

    java多线程的使用和介绍

    ### Java多线程的使用与介绍 #### 什么是多线程? 多线程是指程序能够同时执行多个线程的能力。每个线程都是一个轻量级的进程,可以在单个程序中独立运行,共享该程序的资源。在Java中,多线程是通过`java.lang....

    Java多线程下载网络图片

    在Java编程中,多线程是一项关键技能,尤其在处理并发任务时,如我们的示例——"Java多线程下载网络图片"。这个场景展示了如何利用多线程技术提高程序性能,减少用户等待时间,同时优化系统资源的使用。下面我们将...

    《软件开发基础(Java)》实验报告-Java多线程编程.docx

    在本实验报告中,我们关注的是Java多线程编程,这是Java编程中一个重要的主题,尤其是在并发处理和高性能系统设计中。线程是操作系统分配CPU时间的基本单位,它允许一个程序内部同时执行多个任务,提高了应用程序的...

    Java多线程——线程八锁案例分析.docx

    在Java多线程编程中,线程安全是一个关键概念,特别是在并发访问共享资源时。"线程八锁案例分析"文档中的示例着重展示了`synchronized`关键字如何在控制线程同步方面发挥作用。以下是对这些案例的详细分析: 案例1...

    用java多线程写的贪吃蛇

    在本项目中,"用java多线程写的贪吃蛇"是一个基于Java编程语言实现的经典游戏——贪吃蛇。这个程序利用了Java的多线程技术来管理游戏的各个组件,如蛇、食物以及游戏窗口的更新。让我们深入探讨一下其中涉及的关键...

    操作系统实验 多线程同步与互斥 java编写 有界面

    在“操作系统实验 多线程同步与互斥 java编写 有界面”的实验中,可能需要设计一个图形用户界面(GUI),通过按钮或事件触发线程的创建和同步操作,直观地展示线程间的交互和同步效果。例如,可以模拟银行账户转账,...

Global site tag (gtag.js) - Google Analytics