java同步锁的正确使用

同步锁分类

对象锁(this)

类锁(类的字节码文件对象即类名.class)

字符串锁(比较特别)

应用场景

在多线程下对共享资源的安全操作。

需求:启动5个线程对共享资源total进行安全操作。

同步锁在多线程单例模式下的使用

以上三类同步锁都可以。


package cn.myThread;

public class MyThread implements Runnable {

private static int total =
10;

@Override

public void run() {

synchronized (this){ //使用this对象锁

//synchronized (MyThread.class){ //使用MyThread.class类锁

//synchronized (""){//使用字符串锁

System.out.println(Thread.currentThread().getName()
+ "正在运行");

try {

Thread.sleep(100);

} catch (InterruptedException
e) {

e.printStackTrace();

}

total--;

System.out.println(total);

System.out.println(Thread.currentThread().getName()
+ "线程结束");

}

}

}


package cn.test;

import cn.myThread.MyThread;

public class TestMyThread {

public static void main(String[]
args){

MyThread
myThread = new MyThread();

Thread thread = null;

for (int i = 1 ;
i <= 5 ; i++){

thread = new Thread(myThread,"线程"+i);
//
开启5个线程,传入同一个对象

thread.start();

}

}

}


线程1正在运行

9

线程1线程结束

线程3正在运行

8

线程3线程结束

线程5正在运行

7

线程5线程结束

线程2正在运行

6

线程2线程结束

线程4正在运行

5

线程4线程结束

分析:从运行结果可以看出5个线程串行执行同步锁里面的代码,因为5个线程中的同步锁对象this指向同一个的对象(同步锁对象MyThread.class类锁是同一个对象、同步锁对象 ”” 字符串锁是同一个对象),所以5个线程会串行执行同步锁里面的代码。

同步锁在多线程多例模式下的使用

错误用法


package cn.myThread;

public class MyThread implements Runnable {

private static int total =
10;

@Override

public void run() {

synchronized (this){//使用this对象锁

System.out.println(Thread.currentThread().getName()
+ "正在运行");

try {

Thread.sleep(100);

} catch (InterruptedException
e) {

e.printStackTrace();

}

total--;

System.out.println(total);

System.out.println(Thread.currentThread().getName()
+ "线程结束");

}

}

}


package cn.test;

import cn.myThread.MyThread;

public class TestMyThread {

public static void main(String[]
args){

Thread thread = null;

for (int i = 1 ; i <= 5 ;
i++){

thread = new Thread(new MyThread(),"线程"+i);//开启5个线程,传入5个不同对象

thread.start();

}

}

}


线程2正在运行

线程1正在运行

线程3正在运行

线程5正在运行

线程4正在运行

9

7

9

8

线程1线程结束

线程5线程结束

线程2线程结束

线程3线程结束

6

线程4线程结束

分析:从运行结果可以看出5个线程并行执行同步锁里面的代码,因为5个线程中的同步锁对象this指向5个不同的对象,所以5个线程会同时执行同步锁里面的代码。

正确用法

方式一:


package cn.myThread;

public class MyThread implements Runnable {

private static int total =
10;

@Override

public void run() {

synchronized (MyThread.class){//使用MyThread.class类锁

System.out.println(Thread.currentThread().getName()
+ "正在运行");

try {

Thread.sleep(100);

} catch (InterruptedException
e) {

e.printStackTrace();

}

total--;

System.out.println(total);

System.out.println(Thread.currentThread().getName()
+ "线程结束");

}

}

}


package cn.test;

import cn.myThread.MyThread;

public class TestMyThread {

public static void main(String[]
args){

Thread thread = null;

for (int i = 1 ;
i <= 5 ; i++){

thread = new Thread(new MyThread(),"线程"+i);
//
开启5个线程,传入5个不同对象

thread.start();

}

}

}


线程1正在运行

9

线程1线程结束

线程5正在运行

8

线程5线程结束

线程4正在运行

7

线程4线程结束

线程3正在运行

6

线程3线程结束

线程2正在运行

5

线程2线程结束

分析:从运行结果可以看出5个线程串行执行同步锁里面的代码,因为5个线程中的同步锁对象MyThread.class类锁是同一个对象,所以5个线程会串行执行同步锁里面的代码。

方式二:


package cn.myThread;

public class MyThread implements Runnable {

private static int total =
10;

@Override

public void run() {

synchronized (""){//使用字符串锁

System.out.println(Thread.currentThread().getName()
+ "正在运行");

try {

Thread.sleep(100);

} catch (InterruptedException
e) {

e.printStackTrace();

}

total--;

System.out.println(total);

System.out.println(Thread.currentThread().getName()
+ "线程结束");

}

}

}


package cn.test;

import cn.myThread.MyThread;

public class TestMyThread {

public static void main(String[]
args){

Thread thread = null;

for (int i = 1 ;
i <= 5 ; i++){

thread = new Thread(new MyThread(),"线程"+i);
//
开启5个线程,传入5个不同对象

thread.start();

}

}

}


线程1正在运行

9

线程1线程结束

线程4正在运行

8

线程4线程结束

线程5正在运行

7

线程5线程结束

线程3正在运行

6

线程3线程结束

线程2正在运行

5

线程2线程结束

分析:从运行结果可以看出5个线程串行执行同步锁里面的代码,因为5个线程中的同步锁对象 ”” 字符串锁是同一个对象,所以5个线程会串行执行同步锁里面的代码。

时间: 2024-12-25 04:57:02

java同步锁的正确使用的相关文章

Java同步锁

Java同步锁 线程的同步是为了防止多个线程访问一个数据对象时,对数据造成的破坏.例如:两个线程ThreadA.ThreadB都操作同一个对象Foo对象,并修改Foo对象上的数据. package cn.thread; public class Foo { private int x = 100; public int getX() { return x; } public int fix(int y) { x = x - y; return x; } } package cn.thread;

java 同步锁(synchronized)

java 同步锁(synchronized) 在java中,Synchronized就是一把锁,他可以锁定一个方法,也可以锁定一个方法,我擦,其实这两个东西就是一样的.块不就是一个没有名字的方法么,方法就是一个有名字的块.本文就用块来测试.所谓锁,就是原子操作,把这个锁定的块作为一个整体,就像你上厕所,拉了就要擦屁屁,当然你也可以不擦,如果你不在意出现的问题的话.信号量Semaphore和这个Synchronized 其实实现的功能差不多,不过效率不同,使用的方式也不同.Synchronized

java 同步锁方法

方法一:动态同步锁 class Demo_thread implements Runnable{ public static int sum = 0; public synchronized void add(){//同步锁,为动态方法 for(int i=0;i<5000;i++){ sum = sum + 1; } } public void run(){ add(); } } 动态同步锁适用于Runnable类中不适用与Thread类,因为其锁的对象为当前实例对象,一个Thread类只能跑

Java同步锁——lock与synchronized 的区别【转】

一.Lock和synchronized有以下几点不同: 1)Lock是一个接口,而synchronized是Java中的关键字,synchronized是内置的语言实现,synchronized是在JVM层面上实现的,不但可以通过一些监控工具监控synchronized的锁定,而且在代码执行时出现异常,JVM会自动释放锁定,但是使用Lock则不行,lock是通过代码实现的,要保证锁定一定会被释放,就必须将 unLock()放到finally{} 中: 2)synchronized在发生异常时,会

Java同步锁何时释放?

任何线程进入同步代码块.同步方法之前,必须获得同步监视器的锁定,那么何时会释放这个锁定呢?在程序中,是无法显式释放对同步监视器的锁的,而会在如下几个情况下释放锁. 1.当前线程的同步方法.代码块执行结束的时候释放 2.当前线程在同步方法.同步代码块中遇到break . return 终于该代码块或者方法的时候释放. 3.....出现未处理的error或者exception导致异常结束的时候释放 4.....程序执行了 同步对象 wait 方法 ,当前线程暂停,释放锁 ==============

002-多线程-锁-同步锁-synchronized几种加锁方式、Java对象头和Monitor、Mutex Lock、JDK1.6对synchronized锁的优化实现

一.synchronized概述基本使用 为确保共享变量不会出现并发问题,通常会对修改共享变量的代码块用synchronized加锁,确保同一时刻只有一个线程在修改共享变量,从而避免并发问题. synchronized结论: 1.java5.0之前,协调线程间对共享对象的访问的机制只有synchronized和volatile,但是内置锁在功能上存在一些局限性,jdk5增加了Lock以及ReentrantLock. 2.java5.0,增加了一种新的机制:显式锁ReentrantLock,注意它

java中多线程模拟(多生产,多消费,Lock实现同步锁,替代synchronized同步代码块)

import java.util.concurrent.locks.*; class DuckMsg{ int size;//烤鸭的大小 String id;//烤鸭的厂家和标号 DuckMsg(){ } DuckMsg(int size, String id){ this.size=size; this.id=id; } public String toString(){ return id + " 大小为:" + size; } } class Duck{ private int

【Java】多线程冲突解决——同步锁

转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/5827547.html 解决并行冲突最有效的方法就是加同步锁,主要有以下几种方法: 1:动态方法同步锁:锁当前对象.即调用该方法的类对象优先执行完毕才到下一个任务. public synchronized void 方法() { } 实例代码: import java.lang.Thread.State; import org.omg.CORBA.PUBLIC_MEMBER; public class Thr

[java多线程] - 锁机制&amp;同步代码块&amp;信号量

在美眉图片下载demo中,我们可以看到多个线程在公用一些变量,这个时候难免会发生冲突.冲突并不可怕,可怕的是当多线程的情况下,你没法控制冲突.按照我的理解在java中实现同步的方式分为三种,分别是:同步代码块机制,锁机制,信号量机制. 一.同步代码块 在java的多线程并发开发过程中,我们最常用的方式就是使用同步代码关键字(synchronized).这种方式的使用不是特别复杂,需要注意的只是你需要明确到底同步的是那个对象,只有当同步的对象一致的情况下,才能够控制互斥的操作.一般情况下,我们会同