`
java-mans
  • 浏览: 11459572 次
文章分类
社区版块
存档分类
最新评论

【Java基础】——之线程同步

 
阅读更多

我们先来看一段代码:

import java.util.ArrayList;

public class MyThreadTest {
	private ArrayList<String> list = new ArrayList<String>();
	private byte[] lock = new byte[0];

	private void addData() {
		list.clear();
		for (int n = 0; n < 50; n++) {
			list.add(String.valueOf(n));
		}
		System.out.println(list.size());
	}

	public static void main(String[] args) {
		final MyThreadTest mtt = new MyThreadTest();

		new Thread(new Runnable() {
			@Override
			public void run() {
				mtt.addData();
			}
		}).start();

		new Thread(new Runnable() {
			@Override
			public void run() {
				mtt.addData();
			}
		}).start();
	}
}
输出结果:50、50

在看一段代码:

import java.util.ArrayList;

public class MyThreadTest {
	private ArrayList<String> list = new ArrayList<String>();
	private byte[] lock = new byte[0];

	private void addData() {
		list.clear();
		for (int n = 0; n < 5000; n++) {
			list.add(String.valueOf(n));
		}
		System.out.println(list.size());
	}

	public static void main(String[] args) {
		final MyThreadTest mtt = new MyThreadTest();

		new Thread(new Runnable() {
			@Override
			public void run() {
				mtt.addData();
			}
		}).start();

		new Thread(new Runnable() {
			@Override
			public void run() {
				mtt.addData();
			}
		}).start();
	}
}
输出结果:8828、8971(随机的)

两份代码有什么区别?只不过是把方法中的循环次数改大了而已,但是显然第二次运行结果就不对了,为什么?

这样就引入了线程同步的概念,第一份代码自身不正确,但是运行结果为什么是正确的呢?因为循环次数过少,线程很快就执行完,所以看上去结果是“正确的”。

当我们把这样的程序引入到银行系统中我们猜猜会发生什么?O(∩_∩)O~

在进一步阐述之前,我们需要明确几点:
  A.无论synchronized关键字加在方法上还是对象上,它取得的锁都是对象,而不是把一段代码或函数当作锁――而且同步方法很可能还会被其他线程的对象访问。
  B.每个对象只有一个锁(lock)与之相关联。
  C.实现同步是要很大的系统开销作为代价的,甚至可能造成死锁,所以尽量避免无谓的同步控制。

我们看看改如何修改这个程序:

import java.util.ArrayList;

public class MyThreadTest {
	private ArrayList<String> list = new ArrayList<String>();
	private byte[] lock = new byte[0];

	synchronized private void addData() {
		list.clear();
		for (int n = 0; n < 5000; n++) {
			list.add(String.valueOf(n));
		}
		System.out.println(list.size());
	}

	public static void main(String[] args) {
		final MyThreadTest mtt = new MyThreadTest();

		new Thread(new Runnable() {
			@Override
			public void run() {
				mtt.addData();
			}
		}).start();

		new Thread(new Runnable() {
			@Override
			public void run() {
				mtt.addData();
			}
		}).start();
	}
}
当我们让addData()方法加上同步锁了之后,一次只能有一个线程访问addData()对象,其余线程出于等待状态,输出结果为:5000、5000



分享到:
评论

相关推荐

    Java多线程编程 线程同步机制.docx

    锁正是基于这种思路实现的一种线程同步机制。 在对共享数据加锁后,每个线程在访问共享数据时必须先申请相应的锁。一旦获得锁后,就可以访问共享数据,并且一个锁同一时刻只能被一个线程持有,这意味着获得锁后不会...

    操作系统——实验四 windows中线程的创建和同步控制

    在windows的环境下,创建一个控制台进程,此进程创建两个并发线程,一个是读线程,另一个是写线程。这两个线程共享一个数组A,写线程对数组分别进行10次写操作,每次写操作对A的每个元素赋一个相同的值;读线程对数组...

    Java入门1·2·3——一个老鸟的Java学习心得 高清pdf

    包括Java编程常用知识、Java文件编程、Java文件I/O编程、Java TCP编程、Java UDP编程、Java Swing编程、JDBC编程,最后还给出了一个聊天程序实例和一个数据表操作窗口实例,将Swing、UDP、Java集合类、线程同步、...

    Java线程间同步互斥

    本例将模仿经典的线程同步互斥例子——生产者和消费者问题,来演示  java 强大的多线程机制。生产者和消费者共享一个数据,当数据为0 时,消费者不可访问,生产者可访问数据,每次访问数据加1;当数据到达100 时,...

    秒杀多线程第十六篇 多线程十大经典案例之一 双线程读写队列数据

    在《秒杀多线程系列》的前十五篇中介绍多线程的相关概念,多线程同步互斥问题《秒杀多线程第四篇一个经典的多线程同步问题》及解决多线程同步互斥的常用方法——关键段、事件、互斥量、信号量、读写锁。为了让大家...

    JAVA内存模型——同步操作规则1

    JAVA 数据在内存中的执行流程执行规则:Read和Load ,Store和Write必须顺序执行,但是不必连续执行;一个变量同时只能被一条线程操作,可以被多条

    Java学习源码Java多线程的代码

    在char01包里放置Java多线程基本知识的代码。内容如下: 如何使用多线程 如何得到多线程的一些信息 如何停止线程 如何暂停线程 线程的一些其他用法 在char02包里放置了Java对变量和对象并发访问的知识的代码...

    Java多线程之并发工具类

     主要参考资料:java并发编程的艺术、Java并发——同步工具类  二、CountDownLatch(同步倒数计数器)–不仅仅用于多线程  1.作用:允许一个或多个线程等待其他线程完成操作。  CountDownLatch的构造函数...

    iwehdio#Java_learning_notes#4、多线程知识点1

    1、基础概念多线程与并发(一)——概述、线程状态进程与线程区别?多线程与并发(二)——线程同步、线程协作同步方法和同步代码块?多线程与并发(三)——JUC概述、

    Java多线程基础——Lock类

    Lock类是Java类来提供的功能,丰富的api使得Lock类的同步功能比synchronized的同步更强大。本文对此进行详细介绍,下面跟着小编一起来看下吧

    java并发编程——内存模型

    并发——在操作系统中...线程同步:是指程序用于控制不同线程之间操作发生相对顺序的机制。在Java中,可以通过volatile,synchronized,锁等方式实现同步。本文主要介绍java的通信机制,刚介绍常见通信机制主要包括以下

    Java 课程设计——虚拟城市

    Java课程设计,虚拟城市,同步线程,模拟一个城市中的主要功能,地铁,餐厅,商场,银行,等等。还有特色聊天功能。

    [Java]多线程:共享资源同步——不认真看你会后悔的

    共享资源同步 在进行多线程开发时最令人头痛的问题估计就是对共享资源的控制了吧,今天就让我们谈一谈这个问题吧。 共享资源顾名思义就是需要被多个线程使用的资源,但是很多情况下我们是不能允许多个线程同时使用这...

    Java线程同步与 Java 并发设施.pdf

    ——学习参考资料:仅用于个人学习使用! 本代码仅作学习交流,切勿用于商业用途,否则后果自负。若涉及侵权,请联系,会尽快处理! 未进行详尽测试,请自行调试!

    java实验实验报告 add 实验一:多线程/2.Runnable接口. 实验八:JDBC数据库编程二-存储过程

    重命名 实验三多:线程同步与协作:生产者与消费者 为 实验三:多线程同步与协作:生产者与消费者 实验九:使用jdbc存取大文本 add 实验九:使用jdbc存取大文本. 实验二:多线程打字游戏 add 实验二:多线程...

    最新Java面试题视频网盘,Java面试题84集、java面试专属及面试必问课程

    │ │ 9.JAVA并发编程之多线程并发同步业务场景与解决方案.wmv │ │ │ ├─10.微服务架构之Spring Cloud Eureka 场景分析与实战 │ │ 10.微服务架构之Spring Cloud Eureka 场景分析与实战.wmv │ │ │ ├─11....

    基于某JAVA地剪刀石头布游戏设计——Java课程设计报告材料-.doc

    Java语言支持多个线程的同时执行,并提供多线程之间的同步机制【4】。 通过一个学期的学习,对Java有了一定的了解,为了巩固所学知识,编写一个剪刀石 头布游戏。 1剪刀石头布游戏设计思路阐述 在设计游戏时,我们...

    Java SE实践教程 pdf格式电子书 下载(四) 更新

    第6章 三头六臂——线程和同步的基本概念 109 6.1 讲解 110 6.1.1 什么是线程 110 6.1.2 创建线程 110 6.1.3 线程的生命周期 112 6.1.4 线程的优先级 114 6.1.5 中断线程 115 6.1.6 线程组 116 6.1.7 处理未...

    Java开发详解.zip

    030904_【第9章:多线程】_同步与死锁笔记.pdf 030905_【第9章:多线程】_线程操作案例——生产者和消费者笔记.pdf 030906_【第9章:多线程】_线程生命周期笔记.pdf 031001_【第10章:泛型】_泛型入门笔记.pdf ...

    JAVA入门1.2.3:一个老鸟的JAVA学习心得 PART1(共3个)

    3.4 小结:基本数据类型—— Java中一切数据和运算的基础 63 3.5 习题 65 第4章 Java中的程序执行流程 67 教学视频:1小时57分钟 4.1 顺序执行 67 4.2 使用if-else让程序懂得判断 68 4.2.1 if语句 68 4.2.2 ...

Global site tag (gtag.js) - Google Analytics