1.什么是线程同步?

多线程编程是很有趣的事情,它很容易出现"错误情况",这种情况不是由编码造成的,它是由系统的线程调度造成的,当使用多个线程来访问同一个数据时,很容易出现"偶然情况",出现线程安全问题.

线程安全问题最常见的就是银行取钱问题,铁路售票问题,必须保证甲方在操作数据时候,己方不会影响甲方.类似于公共厕所,一个人占一个坑.

2.下面的例子,将说明为什么要保证线程安全?

package com.amos.concurrent;
/**
* @ClassName: ThreadSynchronizedTest
* @Description: 多线程并发之线程同步
* @author: amosli
* @email:hi_amos@outlook.com
* @date Apr 20, 2014 2:44:29 PM
*/
public class ThreadSynchronizedTest {
public static void main(String[] args) {
new ThreadSynchronizedTest().init();
} private void init() {
final OutPuter outPuter = new OutPuter();
//新建一个线程A
new Thread(new Runnable() {
public void run() {
while (true) {
//休息10ms
try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}
outPuter.output("hi_amos");//输出
}
}
}).start();
//线程B
new Thread(new Runnable() {
public void run() {
while (true) {
try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}
outPuter.output("amosli");
}
}
}).start();
} class OutPuter {
//输出name,逐个字节读取,并输出
public void output(String name) {
int length = name.length();
synchronized (name) {
for (int i = 0; i < length; i++) {
System.out.print(name.charAt(i));
}
System.out.println();
}
}
}
}

输出结果如下图所示:

在多次执行上面的代码后就会发现出现问题了,这是因为线程A和线程B在执行output方法时,系统调度出现了问题,导致了上面的问题,这种情况出现的概率相对较小,但这种小概率的事件也是要解决的.下面将介绍如何解决这种问题.

3.解决方法1--同步代码块

只需要将上面的方法加上synchronized关键字即可

public void output2(String name) {
int length = name.length();
synchronized (this) {
for (int i = 0; i < length; i++
) {
System.out.print(name.charAt(i));
}
System.out.println();
}

}

在要多次访问的代码块前加上synchronized关键字,即表示加上排队系统,线程A只有等线程B执行完了才能访问同一个代码块.

这里要注意this,this表示的是当前对象,这里this也可以用Outputer.class代替.

4.解决方法2--同步方法

public synchronized void output(String name) {
int length = name.length();
for (int i = 0; i < length; i++) {
System.out.print(name.charAt(i));
}
System.out.println();
}

同步方法,即是在要多次访问的方法前面加上synchronized关键字.

注意:

1.synchronized关键字可以修饰方法,代码块,但不能修饰构造器,属性等;

2.同时synchronized关键字最好一个方法中只用一次,否则可能造成死锁.

3.任何时刻只能有一个线程可以获得对同步监视器的锁定,当同步代码块执行完成后,该线程会释放对该同步监视器的锁定.

上面的代码可以改写如下:

package com.amos.concurrent;

/**
* @ClassName: ThreadSynchronizedTest
* @Description: 多线程并发之线程安全
* @author: amosli
* @email:hi_amos@outlook.com
* @date Apr 20, 2014 2:44:29 PM
*/
public class ThreadSynchronizedTest {
public static void main(String[] args) {
new ThreadSynchronizedTest().init();
} private void init() {
final OutPuter outPuter = new OutPuter();
//新建一个线程
new Thread(new Runnable() {
public void run() {
while (true) {
//休息10ms
try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}
outPuter.output("hi_amos");//输出
}
}
}).start(); new Thread(new Runnable() {
public void run() {
while (true) {
try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}
outPuter.output("amosli");
}
}
}).start();
} static class OutPuter {
//输出name,逐个字节读取,并输出
public synchronized void output(String name) {
int length = name.length();
for (int i = 0; i < length; i++) {
System.out.print(name.charAt(i));
}
System.out.println();
}
public void output2(String name) {
int length = name.length();
synchronized (OutPuter.class) {
for (int i = 0; i < length; i++) {
System.out.print(name.charAt(i));
}
System.out.println();
}
}
public synchronized static void output3(String name) {
int length = name.length();
for (int i = 0; i < length; i++) {
System.out.print(name.charAt(i));
}
System.out.println();
}
}
}

java核心知识点学习----多线程并发之线程同步的更多相关文章

  1. Java核心知识点学习----多线程并发之线程间的通信,notify,wait

    1.需求: 子线程循环10次,主线程循环100次,这样间隔循环50次. 2.实现: package com.amos.concurrent; /** * @ClassName: ThreadSynch ...

  2. Java核心知识点学习----多线程中的阻塞队列,ArrayBlockingQueue介绍

    1.什么是阻塞队列? 所谓队列,遵循的是先进先出原则(FIFO),阻塞队列,即是数据共享时,A在写数据时,B想读同一数据,那么就将发生阻塞了. 看一下线程的四种状态,首先是新创建一个线程,然后,通过s ...

  3. Java核心知识点学习----使用Condition控制线程通信

    一.需求 实现线程间的通信,主线程循环3次后,子线程2循环2次,子线程3循环3次,然后主线程接着循环3次,如此循环3次. 即:A->B->C---A->B->C---A-> ...

  4. Java核心知识点学习----多线程 倒计时记数器CountDownLatch和数据交换的Exchanger

    本文将要介绍的内容都是Java5中的新特性,一个是倒计时记数器---CountDownLatch,另一个是用于线程间数据交换的Exchanger. 一.CountDownLatch 1.什么是Coun ...

  5. java核心知识点学习----多线程间的数据共享和对象独立,ThreadLocal详解

    线程内的数据共享与对象独立,举例:张三给李四转钱,开启A线程去执行转钱这个动作,刚好同时王五给赵六转钱,开启B线程去执行转钱,因为是调用的同样一个动作或者说对象,所以如果不能保证线程间的对象独立,那么 ...

  6. java核心知识点学习----多线程间的数据共享的几种实现方式比较

    需求:设计4个线程,其中两个线程每次对j增加1,另外两个线程对j减少1. 实现数据共享的几种方式比较: 1.使用同一个runnable对象 如果每个线程执行的代码相同,那么可以使用同一个runnabl ...

  7. Java核心知识点学习----线程中如何创建锁和使用锁 Lock,设计一个缓存系统

    理论知识很枯燥,但这些都是基本功,学完可能会忘,但等用的时候,会发觉之前的学习是非常有意义的,学习线程就是这样子的. 1.如何创建锁? Lock lock = new ReentrantLock(); ...

  8. Java核心知识点学习----线程同步工具类,CyclicBarrier学习

    线程同步工具类,CyclicBarrier日常开发较少涉及,这里只举一个例子,以做备注.N个人一块出去玩,相约去两个地方,CyclicBarrier的主要作用是等待所有人都汇合了,才往下一站出发. 1 ...

  9. Java核心知识点学习----线程中的Semaphore学习,公共厕所排队策略

    1.什么是Semaphore? A counting semaphore. Conceptually, a semaphore maintains a set of permits. Each acq ...

随机推荐

  1. CSAPP(前言)

    很久之前就听过有过CSAPP这本书的传闻了,今天终于决定上手这本神作:既然是神作,就要仔细拜读一下,今天看了一下前言部分还真的令人耳目一新,单单是前言部分就让我学习到几个新的知识点: 1.c和Java ...

  2. 【学】CSS3的3D动画 ——3D旋转之骰子样式的钟表(2)上

    这个是3D旋转的进阶版,是一个类似与骰子的正方体.这个版本只有秒数的个位数,还没有写整个钟表,下面那个版本好好想想该怎么写 这个效果需要用到transform-style: preserve-3d. ...

  3. JSTL标签库中<c:choose></c:choose>不能放JSP页面<!-- -->注释

    笔者最近在使用JSTL标签库的<c:choose>标签时候,发现在该标签体中加了JSP的<!-- -->注释时,总是会显示报错信息.错误的信息如下: <span styl ...

  4. Codeforces 721C [dp][拓扑排序]

    /* 题意:给你一个有向无环图.给一个限定t. 问从1点到n点,在不超过t的情况下,最多可以拜访几个点. 保证至少有一条路时限不超过t. 思路: 1.由无后向性我们可以知道(取决于该图是一个DAG), ...

  5. poj 2513 Colored Sticks trie树+欧拉图+并查集

    点击打开链接 Colored Sticks Time Limit: 5000MS   Memory Limit: 128000K Total Submissions: 27955   Accepted ...

  6. 黑马程序员_JAVA基础知识总结3

    ------- android培训.java培训.期待与您交流! ---------- Java源文件的扩展名是.java,编译之后生成.class的文件.所有的类都有一个共同的继承祖先Object类 ...

  7. 在后台 .cs 中执行前台的js 函数

    <script type="text/javascript" language="javascript"> <!-- function ope ...

  8. 9. Linux远程登录

    1. 检查网络是否通畅 C:\Users\cfm>ping 192.168.232.131 正在 Ping 192.168.232.131 具有 32 字节的数据:来自 192.168.232. ...

  9. cookie sessionStorage localStorage 区别

    sessionStorage 和 localStorage 是HTML5 Web Storage API 提供的,可以方便的在web请求之间保存数据.有了本地数据,就可以避免数据在浏览器和服务器间不必 ...

  10. Corba概念(GIOP、IIOP、IOR、ORB、IDL)

    CORBA公用对象请求代理(调度)程序体系结构(Common Object Request Broker Architecture),缩写为 CORBA,是对象管理组织(Object Manageme ...