`
shuidexiongdi
  • 浏览: 73262 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

(转)浅谈Java多线程的同步问题

 
阅读更多

 

多线程的同步依靠的是对象锁机制,synchronized关键字的背后就是利用了封锁来实现对共享资源的互斥访问。

下面以一个简单的实例来进行对比分析。实例要完成的工作非常简单,就是创建10个线程,每个线程都打印从099100个数字,我们希望线程之间不会出现交叉乱序打印,而是顺序地打印。

先来看第一段代码,这里我们在run()方法中加入了synchronized关键字,希望能对run方法进行互斥访问,但结果并不如我们希望那样,这是因为这里synchronized锁住的是this对象,即当前运行线程对象本身。代码中创建了10个线程,而每个线程都持有this对象的对象锁,这不能实现线程的同步。

复制代码
代码
package com.vista;

class MyThread implements java.lang.Runnable
{
    
private int threadId;

    
public MyThread(int id)
    {
        
this.threadId = id;
    }
    @Override
    
public synchronized void run() 
    {
        
for (int i = 0; i < 100++i)
        {
            System.out.println(
"Thread ID: " + this.threadId + " : " + i);
        }
    }
}
public class ThreadDemo
{
    
/**
     * 
@param args
     * 
@throws InterruptedException 
     
*/
    
public static void main(String[] args) throws InterruptedException
    {
        
for (int i = 0; i < 10++i)
        {
            
new Thread(new MyThread(i)).start();
            Thread.sleep(
1);
        }
    }
}
复制代码

      从上述代码段可以得知,要想实现线程的同步,则这些线程必须去竞争一个唯一的共享的对象锁。

      基于这种思想,我们将第一段代码修改如下所示,在创建启动线程之前,先创建一个线程之间竞争使用的Object对象,然后将这个Object对象的引用传递给每一个线程对象的lock成员变量。这样一来,每个线程的lock成员都指向同一个Object对象。我们在run方法中,对lock对象使用synchronzied块进行局部封锁,这样就可以让线程去竞争这个唯一的共享的对象锁,从而实现同步。

复制代码
代码
package com.vista;

class MyThread implements java.lang.Runnable
{
    
private int threadId;
    
private Object lock;
    
public MyThread(int id, Object obj)
    {
        
this.threadId = id;
        
this.lock = obj;
    }
    @Override
    
public  void run() 
    {
        
synchronized(lock)
        {
            
for (int i = 0; i < 100++i)
            {
                System.out.println(
"Thread ID: " + this.threadId + " : " + i);
            }
        }
    }
}
public class ThreadDemo
{
    
/**
     * 
@param args
     * 
@throws InterruptedException 
     
*/
    
public static void main(String[] args) throws InterruptedException
    {
        Object obj 
= new Object();
        
for (int i = 0; i < 10++i)
        {
            
new Thread(new MyThread(i, obj)).start();
            Thread.sleep(
1);
        }
    }
}
复制代码

从第二段代码可知,同步的关键是多个线程对象竞争同一个共享资源即可,上面的代码中是通过外部创建共享资源,然后传递到线程中来实现。我们也可以利用类成员变量被所有类的实例所共享这一特性,因此可以将lock用静态成员对象来实现,代码如下所示:

 

复制代码
代码
package com.vista;

class MyThread implements java.lang.Runnable
{
    
private int threadId;
    
private static Object lock = new Object();
    
public MyThread(int id)
    {
        
this.threadId = id;
    }
    @Override
    
public  void run() 
    {
        
synchronized(lock)
        {
            
for (int i = 0; i < 100++i)
            {
                System.out.println(
"Thread ID: " + this.threadId + " : " + i);
            }
        }
    }
}
public class ThreadDemo 
{
    
/**
     * 
@param args
     * 
@throws InterruptedException 
     
*/
    
public static void main(String[] args) throws InterruptedException
    {
        
for (int i = 0; i < 10++i)
        {
            
new Thread(new MyThread(i)).start();
            Thread.sleep(
1);
        }
    }
}
复制代码

再来看第一段代码,实例方法中加入sychronized关键字封锁的是this对象本身,而在静态方法中加入sychronized关键字封锁的就是类本身。静态方法是所有类实例对象所共享的,因此线程对象在访问此静态方法时是互斥访问的,从而可以实现线程的同步,代码如下所示:

复制代码
代码
package com.vista;

class MyThread implements java.lang.Runnable
{
    
private int threadId;
    
    
public MyThread(int id)
    {
        
this.threadId = id;
    }
    @Override
    
public  void run() 
    {
        taskHandler(
this.threadId);
    }
    
private static synchronized void taskHandler(int threadId)
    {
        
for (int i = 0; i < 100++i)
        {
            System.out.println(
"Thread ID: " + threadId + " : " + i);
        }
    }
}
public class ThreadDemo
{
    
/**
     * 
@param args
     * 
@throws InterruptedException 
     
*/
    
public static void main(String[] args) throws InterruptedException
    {
        
for (int i = 0; i < 10++i)
        {
            
new Thread(new MyThread(i)).start();
            Thread.sleep(
1);
        }
    }
}
复制代码
 
 

 关于另一种同步方法(采用lock进行控制),可参考下面文章

http://blog.csdn.net/fw0124/article/details/6672522

分享到:
评论

相关推荐

    浅谈Java多线程编程.pdf

    "浅谈Java多线程编程" 从标题和描述可以看出,这篇文章的主题是讨论Java多线程编程的相关知识点。 多线程编程的概念 Java语言的一个重要特点是支持多线程机制,这使得Java程序可以支持多程序并发执行,从而提高...

    浅谈java多线程编程

    本文将深入探讨Java多线程的优缺点、创建方式以及线程安全与同步机制。 **一、多线程的优缺点** 1. **优点** - **资源利用率更高**:多线程可以充分利用多核处理器资源,使得CPU在等待IO操作或其他阻塞时仍有工作...

    浅谈Java的多线程机制.pdf

    "浅谈Java的多线程机制" 本文主要讨论了Java语言中的多线程机制,旨在提高应用程序的性能和实时控制性能。 Java提供了多线程编程模型,使得在一个程序中可以同时执行多个小任务,从而最大限度地利用CPU资源。 首先...

    浅谈JAVA中多线程的实现.zip

    了解并熟练掌握这些Java多线程的概念和实践技巧,对于编写高性能、并发友好的Java应用至关重要。在实际开发中,合理地使用多线程可以提高程序的运行效率,但也需要考虑到线程安全、资源竞争等问题,避免出现死锁、...

    浅谈JAVA语言的多线程技术.pdf

    浅谈JAVA语言的多线程技术 一、多线程技术的概述 JAVA语言作为一种面向对象的编程语言,它具有平台独立性、安全性、网络化、多线程、面向对象等特点。其线程机制在实践中广泛应用而受到编程者的极大关心。本文就...

    浅谈Java多线程编程中Boolean常量的同步问题

    在Java多线程编程中,确保...总之,Java多线程编程中,对`Boolean`常量的同步必须谨慎处理,避免因为自动装箱和对象引用的特性导致的同步失效。通过正确理解和使用同步机制,我们可以确保多线程环境下的数据一致性。

    浅谈Java多线程处理中Future的妙用(附源码)

    "浅谈Java多线程处理中Future的妙用" 在Java多线程处理中,Future是一个非常重要的概念,它可以帮助我们更好地处理并发任务。Future是一个未来对象,里面保存着线程处理结果,它像一个提货凭证,拿着它你可以随时去...

    Java同步机制浅谈

    `synchronized`关键字主要用于解决Java应用程序中的多线程同步问题。它可以应用于方法和代码块,帮助开发者控制对共享资源的访问,从而保证数据的一致性和安全性。 1. **同步方法**:当`synchronized`关键字用于...

    浅谈JAVA中多线程的实现.pdf

    在Java开发中,多线程技术是一项重要的编程技能,它允许同时运行两个或多个部分,这些部分...在实际开发中,根据不同的需求选择合适的多线程实现方法,并注意线程安全和同步控制问题,是编写稳定高效Java程序的关键。

    浅谈Java多线程实现及同步互斥通讯

    浅谈Java多线程实现及同步互斥通讯 多线程实现方式: Java中的多线程实现方式共有两种:通过继承Thread类和通过实现Runnable接口。下面我们来详细了解这两种方式: 1. 通过继承Thread类来实现多线程: 通过继承...

    浅谈java多线程wait,notify

    在Java多线程编程中,wait和notify是两个非常重要的机制,用于实现线程之间的通信和同步。在本文中,我们将通过示例代码详细介绍Java多线程wait和notify的使用,帮助读者更好地理解和掌握这两个机制。 wait机制 在...

    浅谈java多线程 join方法以及优先级方法

    总结起来,Java多线程中的`join()`方法用于线程间的同步,确保一个线程在另一个线程完成后再继续执行。线程的优先级则影响线程调度,但不是绝对的执行顺序保证。理解并熟练运用这些概念对于编写高效的并发程序至关...

    浅谈多线程_让程序更高效的运行

    总的来说,多线程是提高程序并发性和效率的重要手段,但同时也引入了线程安全、死锁等问题,需要开发者精心设计和管理线程的生命周期,正确使用同步和异步机制,以及处理好临界资源的访问,以保证程序的稳定和高效...

    浅谈Java多线程的优点及代码示例

    Java多线程是一种编程技术,允许程序同时执行多个任务,从而提高资源利用率、简化程序设计并加快程序响应速度。在Java中,多线程通过创建线程对象来实现,每个线程代表程序中的一个独立执行流。 **资源利用率更好**...

    浅谈Java线程的生命周期——北大青鸟佳音旗舰.docx

    为了保证数据一致性,当多个线程可能访问共享资源时,需要使用同步机制,如`synchronized`关键字或`java.util.concurrent`包中的工具类。 以下是一个简单的示例,展示了两个线程交替打印"A"和"B": ```java public...

    浅谈java线程join方法使用方法

    浅谈Java线程join方法使用方法 Java中的线程join方法是一种实现线程同步的方式,可以将原本并行执行的多线程方法变成串行执行的。在Java中,线程join方法的作用是使当前线程等待另一个线程的结束,然后再继续执行...

    浅谈java集合框架

    ### 浅谈Java集合框架 Java集合框架是一个用于存储、操作和检索一组对象的强大工具集。集合框架的设计目的是为了提供一套高效且灵活的数据结构来满足不同的应用需求。本篇文章将详细探讨Java集合框架中的一些核心...

    浅谈java连接池

    - 在Java中,通过`synchronized`关键字实现线程同步,确保连接的并发安全。 2. **多数据库服务器与多用户支持** - 设计单例模式的连接池管理类,根据配置文件中的数据库信息动态创建和管理不同的连接池。 3. **...

    浅谈java!

    它包含了Java的核心概念和技术,如类、对象、异常处理、线程等。在这一阶段,学习者应重点掌握以下几点: - **语法基础**:熟悉Java的基本语法结构,如变量定义、运算符、控制流语句等。 - **面向对象**:深刻理解...

Global site tag (gtag.js) - Google Analytics