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

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

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

 代码Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->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块进行局部封锁,这样就可以让线程去竞争这个唯一的共享的对象锁,从而实现同步。

 代码Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->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用静态成员对象来实现,代码如下所示:

 代码Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->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关键字封锁的就是类本身。静态方法是所有类实例对象所共享的,因此线程对象在访问此静态方法时是互斥访问的,从而可以实现线程的同步,代码如下所示:

 代码Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->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);
}
}
}

作者:洞庭散人

出处:http://phinecos.cnblogs.com/    

本博客遵从Creative Commons Attribution 3.0 License,若用于非商业目的,您可以自由转载,但请保留原作者信息和文章链接URL。

浅谈Java多线程的同步问题 【转】的更多相关文章

  1. 转载:浅谈Java多线程的同步问题【很好我就留下来,多分共享】

    转载:http://www.cnblogs.com/phinecos/archive/2010/03/13/1684877.html#undefined 多线程的同步依靠的是对象锁机制,synchro ...

  2. 浅谈 Java 多线程(一) --- JMM

    为什么使用多线程 更多的处理器核心数(硬件的发展使 CPU 趋向于更多的核心数,如果不能充分利用,就无法显著提升程序的效率) 更快的响应时间(复杂的业务场景下,会存在许多数据一致性不强的操作,如果将这 ...

  3. 浅谈Java多线程同步机制之同步块(方法)——synchronized

    在多线程访问的时候,同一时刻只能有一个线程能够用 synchronized 修饰的方法或者代码块,解决了资源共享.下面代码示意三个窗口购5张火车票: package com.jikexueyuan.t ...

  4. 浅谈Java多线程

    线程与进程 什么是进程? 当一个程序进入内存中运行起来它就变为一个进程.因此,进程就是一个处于运行状态的程序.同时进程具有独立功能,进程是操作系统进行资源分配和调度的独立单位. 什么是线程? 线程是进 ...

  5. 浅谈Java多线程中的join方法

    先上代码 新建一个Thread,代码如下: package com.thread.test; public class MyThread extends Thread { private String ...

  6. 浅谈java类集框架和数据结构(2)

    继续上一篇浅谈java类集框架和数据结构(1)的内容 上一篇博文简介了java类集框架几大常见集合框架,这一篇博文主要分析一些接口特性以及性能优化. 一:List接口 List是最常见的数据结构了,主 ...

  7. 浅谈Java线程安全

    浅谈Java线程安全 - - 2019-04-25    17:37:28 线程安全 Java中的线程安全 按照线程安全的安全程序由强至弱来排序,我们可以将Java语言中各种操作共享的数据分为以下五类 ...

  8. 浅谈JAVA集合框架

    浅谈JAVA集合框架 Java提供了数种持有对象的方式,包括语言内置的Array,还有就是utilities中提供的容器类(container classes),又称群集类(collection cl ...

  9. 浅谈Java的集合框架

    浅谈Java的集合框架 一.    初识集合 重所周知,Java有四大集合框架群,Set.List.Queue和Map.四种集合的关注点不同,Set 关注事物的唯一性,List 关注事物的索引列表,Q ...

随机推荐

  1. (NO.00003)iOS游戏简单的机器人投射游戏成形记(一)

    这是一个简单的机器人投射游戏,主要来熟悉物理引擎的一些东西.你可以把它认为是机器人投篮;尽管投出的是抛物线,但不是篮球而是子弹,速度也较快. 游戏玩法是玩家选择机器人,移动机器人手臂瞄准篮框,然后发射 ...

  2. 常用Petri网模拟软件工具简介

    常用Petri网模拟软件工具简介 首先要介绍的的一个非常有名的Petri 网网站--Petri Nets World:       http://www.informatik.uni-hamburg. ...

  3. Leetcode_28_Implement strStr

    本文是在学习中的总结,欢迎转载但请注明出处:http://blog.csdn.net/pistolove/article/details/41452047 Implement strStr(). Re ...

  4. OC语言大总结(上)

    根据OC学习的知识点,总结了一下,希望能帮到大家! 作者:韩俊强  未经允许,请勿转载! 关注博主:http://weibo.com/hanjunqiang 第一节类于对象   类与对象http:// ...

  5. Which is Better: Forms Servlet or Socket Mode?

    URL:http://blogs.oracle.com/stevenChan/2009/06/which_is_better_forms_servlet_or_socket_mode.html Man ...

  6. STL算法设计理念 - 函数适配器

    1)函数适配器的理论知识 2)常用函数函数适配器 标准库提供一组函数适配器,用来特殊化或者扩展一元和二元函数对象.常用适配器是: 1.绑定器(binder): binder通过把二元函数对象的一个实参 ...

  7. 《java入门第一季》之面向对象(成员方法)

    /* 类的组成:成员变量,成员方法 又加入了一个新的成员:构造方法. 以后再提(类的组成): 成员变量 构造方法 成员方法 根据返回值: void类型 非void类型 形式参数: 空参方法 非空参方法 ...

  8. Using PL/SQL APIs as Web Services

    Overview Oracle E-Business Suite Integrated SOA Gateway allows you to use PL/SQL application program ...

  9. HBase事务

    众所周知,ACID是指原子性(Atomicity),一致性(Consistency),隔离性(Isolation)和持久性(Durability). HBase对同一行数据的操作提供ACID保证.HB ...

  10. android Material Design详解

    原文地址:http://blog.csdn.net/jdsjlzx/article/details/41441083/ 前言 我们都知道Marterial Design是Google推出的全新UI设计 ...