三种方法:

同步代码块:

synchronized(obj)

{

//obj表示同步监视器,是同一个同步对象

/**.....

TODO SOMETHING

*/

}

 

同步方法

格式:

在方法上加上synchronized修饰符即可。(一般不直接在run方法上加!)

synchronized 返回值类型 方法名(参数列表)

{

/**.....

TODO SOMETHING

*/

}

同步方法的同步监听器其实的是 this

静态方法的同步

同步方法

同步代码块

static不能和 this连用

静态方法的默认同步锁是当前方法所在类的.class对象

同步锁

jkd1.5后的另一种同步机制:

通过显示定义同步锁对象来实现同步,这种机制,同步锁应该使用Lock对象充当。

在实现线程安全控制中,通常使用ReentrantLock(可重入锁)。使用该对象可以显示地加锁和解锁。

具有与使用 synchronized 方法和语句所访问的隐式监视器锁相同的一些基本行为和语义,但功能更强大。

public class X {

private final ReentrantLock lock = new ReentrantLock();

//定义需要保证线程安全的方法

public void  m(){

//加锁

lock.lock();

try{

//... method body

}finally{

//在finally释放锁

lock.unlock();

}

}

}

修改后的例子:

//同步代码块

package july7;

class SellDemo implements Runnable{

private int num = 50;

@Override

public void run() {

for (int i = 0; i < 200; i++) {

synchronized (this) {

if(num > 0){

try {

//因为它不可以直接调用getName()方法,所以必须要获取当前线程。

Thread.sleep(10);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println(Thread.currentThread().getName()+"卖出第"+num--+"张票!");

}

}

}

}

}

public class Demo3 {

public static void main(String[] args) {

SellDemo s = new SellDemo();

new Thread(s,"A").start();

new Thread(s,"B").start();

new Thread(s,"C").start();

}

}

//同步方法

package july7;

//同步方法

class FinalDemo1 implements Runnable {

private int num = 50;

@Override

public void run() {

for (int i = 0; i < 100; i++) {

gen();

}

}

public synchronized void gen() {

for (int i = 0; i < 100; i++) {

if (num > 0) {

try {

Thread.sleep(10);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println(Thread.currentThread().getName() + "卖出了第"

+ num-- + "张票!");

}

}

}

}

public class Demo6 {

public static void main(String[] args) {

FinalDemo1 f = new FinalDemo1();

new Thread(f, "A").start();

new Thread(f, "B").start();

new Thread(f, "C").start();

}

}

//线程同步锁

package july7;

import java.util.concurrent.locks.ReentrantLock;

//同步锁

class FinalDemo2 implements Runnable {

private int num = 50;

private final ReentrantLock lock = new ReentrantLock();

@Override

public void run() {

for (int i = 0; i < 100; i++) {

gen();

}

}

public void gen() {

lock.lock();

try{

//for (int i = 0; i < 100; i++) {

if (num > 0) {

try {

Thread.sleep(10);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println(Thread.currentThread().getName() + "卖出了第"

+ num-- + "张票!");

}

//}

}finally{

lock.unlock();

}

}

}

public class Demo7 {

public static void main(String[] args) {

FinalDemo2 f = new FinalDemo2();

new Thread(f, "A").start();

new Thread(f, "B").start();

new Thread(f, "C").start();

}

}

java 多线程安全问题的解决方法的更多相关文章

  1. python编程系列---多线程共享全局变量出现了安全问题的解决方法

    多线程共享全局变量出现了安全问题的解决方法 当多线程共享全局变量时,可能出现安全问题,解决机制----互斥锁:即在在一段与全局变量修改相关的代码中,假设一个时间片不足以完成全局变量的修改,就在这段代码 ...

  2. Java 多线程安全问题简单切入详细解析

    线程安全 假如Java程序中有多个线程在同时运行,而这些线程可能会同时运行一部分的代码.如果说该Java程序每次运行的结果和单线程的运行结果是一样的,并且其他的变量值也都是和预期的结果是一样的,那么就 ...

  3. Tomcat 优化 java.lang.OutOfMemoryError: Java heap space 的解决方法

    Tomcat 优化 java.lang.OutOfMemoryError: Java heap space 的解决方法 java.lang.OutOfMemoryError: Java heap sp ...

  4. java.lang.ClassNotFoundException的解决方法

    java.lang.ClassNotFoundException的解决方法   出现这个问题的原因可能很多,但是最终原因都是部署的项目文件中没有这个类包. 那么出错的点在哪呢?逐一排除! 1.首先在项 ...

  5. Tomcat部署java项目java.lang.OutOfMemoryError异常解决方法

    java.lang.OutOfMemoryError异常解决方法 Window系统环境下,在catalina.bat文件第一行添加以下内容 set JAVA_OPTS=-Xms512m -Xmx512 ...

  6. java基础知识回顾之java Thread类学习(四)--java多线程安全问题(锁)

    上一节售票系统中我们发现,打印出了错票,0,-1,出现了多线程安全问题.我们分析为什么会发生多线程安全问题? 看下面线程的主要代码: @Override public void run() { // ...

  7. 对于jfinal中java.lang.Long cannot be cast to java.lang.Integer的解决方法

    @Jfinal 老大提供的解决方法 当数据库字段为 int 型(有符号int型),但是如果在 sql 中使用了某些函数,jdbc 会自动转型为 long,例如:select sum(money) fr ...

  8. android 工程里缺少 R.java 文件原因和解决方法

    作为新手,学习android 的时候难免要导入一些示例,目的为了更加了解android各种API用法,顺便也可以学习下别人代码的写法. 可是导入android源码后,基本都有错误,R.java也不会自 ...

  9. Java中线程出现Exception in thread "Thread-0" java.lang.IllegalMonitorStateException异常 解决方法

    代码 package thread; public class TestChongNeng { public static void main(String[] args) { Thread t1 = ...

随机推荐

  1. arcgis访问百度地图

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  2. BZOJ 4420二重镇题解

    链接 思路借鉴了这个博客: 我们可以想到状压dp 用一个十进制数来表示状态,即第i位表示位置i处的物品等级 用f[i][j][k]表示第i天,仓库的物品等级为j,状态为k时的最大收益 但是状态数貌似很 ...

  3. RapidMiner Studio 入门

    http://docs.rapidminer.com/studio/getting-started/ RapidMiner Studio 入门 FEIFEI MA 2015-12-07RAPIDMIN ...

  4. 初识Django(DNS原理及web框架)

    DNS的原理 假设www.abc.com的主机要查询www.xyz.abc.com的服务器ip地址. 知识点 1.hosts文件:以静态映射的方式提供IP地址与主机名的对照表,类似ARP表 2.域:a ...

  5. zend studio打开文件提示unsupported character encoding

    zend studio打开文件提示unsupported character encoding,是文件的编码方式错误. 有可能是PHP代码中,charset={CHARSET} ,用了变量的形式调用编 ...

  6. php的一些误解

    1.php函数和方法是不用的:类的方法可以设定访问权限,需要通过对象或者类来调用:函数是公共的,都可以使用.

  7. NPOI操作、导出Excel

    //使用NPOI操作Excel private void ExcelNPOI(System.Data.DataTable dt, HttpContext context) { IWorkbook wo ...

  8. 小爬爬4.协程基本用法&&多任务异步协程爬虫示例(大数据量)

    1.测试学习 (2)单线程: from time import sleep import time def request(url): print('正在请求:',url) sleep() print ...

  9. 对The Curse of Dimensionality(维度灾难)的理解

    一个特性:低维(特征少)转向高维的过程中,样本会变的稀疏(可以有两种理解方式:1.样本数目不变,样本彼此之间距离增大.2.样本密度不变,所需的样本数目指数倍增长). 高维度带来的影响: 1.变得可分. ...

  10. java对象转化为json字符串并传到前台

    package cc.util; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import ...