多线程 synchronized关键字

在多线程情况下,当多个线程操作同一个资源的时候,会出现安全问题,例如脏读(一个线程咋读取变量的时候,值已经被另一个线程改变)。

synchronized关键字:可用来同步方法或者代码块。有关synchronized,总结一下几条。

  1 synchronized关键字锁的是对象,当多个对象会创建多个锁,而达不到同步的效果。

  2 只有操作公共资源的时候才需要上锁,非公共资源没必要上锁。

  3 synchronized关键字拥有可重入锁。

  4 异常出现的时候,会自动释放锁。

  5 同步不具备继承性。

  6 sleep()方法不会释放锁。

  7wait()方法会释放锁。

  8 synchronized可同步方法,也可以同步代码块。

下面对其中几条进行验证;

方法类:

public class MyMethod {

	synchronized public void methodA(String username) throws InterruptedException{
		System.out.println(username);
		if(username.equals("a")){

			System.out.println(Thread.currentThread().getName()+"  into methodA");
			Thread.sleep(2000);
			System.out.println(Thread.currentThread().getName()+"  out methodA");
		}
		else {
			System.out.println(Thread.currentThread().getName()+"  into methodB");
			Thread.sleep(1000);
			System.out.println(Thread.currentThread().getName()+"  out methodB");
		}
		/*while(true){

		}*/
	}
	//synchronized 锁代码块
	public static void methodB(String lock) throws InterruptedException{
		synchronized (lock) {
			System.out.println(Thread.currentThread().getName()+"  into lock");
			Thread.sleep(1000);
			System.out.println(Thread.currentThread().getName()+"  out lock");

		}
	}
}

  

主线程:synchronized同步代码块。synchronized(this)锁的是当前对象。

public class Run {

	public static void main(String[] args) throws InterruptedException {

		MyMethod m1=new MyMethod();
		MyMethod m2=new MyMethod();
		String lock="";
		Thread t1 =new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					m1.methodB(lock);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		},"t1");
		Thread t2 =new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					m1.methodB(lock);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		},"t2");
		t1.start();
		t2.start();

	}

}

  控制台:

t2  into lock
t2  out lock
t1  into lock
t1  out lock

  synchronized同步方法,修改主线程如下

public class Run {

	public static void main(String[] args) throws InterruptedException {

		MyMethod m1=new MyMethod();
		MyMethod m2=new MyMethod();
		String lock="";
		Thread t1 =new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					m1.methodA("a");
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		},"t1");
		Thread t2 =new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					m1.methodA("b");
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		},"t2");
		t1.start();
		t2.start();

	}

}

  控制台输出:

b
t2  into methodB
t2  out methodB
a
t1  into methodA
t1  out methodA

  可以发现达到同步的效果。

再次修改主线程代码如下:

public class Run {

	public static void main(String[] args) throws InterruptedException {

		MyMethod m1=new MyMethod();
		MyMethod m2=new MyMethod();
		String lock="";
		Thread t1 =new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					m1.methodA("a");
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		},"t1");
		Thread t2 =new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					m2.methodA("b");
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		},"t2");
		t1.start();
		t2.start();

	}

}

  控制台如下

b
a
t1  into methodA
t2  into methodB
t2  out methodB
t1  out methodA

  并且多次执行main方法,发现控制台打印顺序不同。此处调用的是两个对象,所以jvm会创建两个锁,互不影响,所以在锁,只能锁一个对象中的方法。证明synchronized锁的是对象。此过程中,我还测试了静态方法,当把methodA()方法改为静态的时候

两个对象一样会有同步的效果。

可重入锁概念:自己可以再次获取自己的内部锁。如有一个线程获得了某个对象的锁,此时这个对象还没有释放,当其再次想获取这个对象的锁的时候,还是可以获取的,否则会造成死锁。

  

  每一个优秀的人,都有一段沉默的时光。不抱怨,不诉苦,最后度过那段感动自己的日子。

原文地址:https://www.cnblogs.com/hrlizhi/p/9409285.html

时间: 2024-11-03 11:50:10

多线程 synchronized关键字的相关文章

Java对象锁和类锁全面解析(多线程synchronized关键字)

最近工作有用到一些多线程的东西,之前吧,有用到synchronized同步块,不过是别人怎么用就跟着用,并没有搞清楚锁的概念.最近也是遇到一些问题,不搞清楚锁的概念,很容易碰壁,甚至有些时候自己连用没用对都不知道. 今天把一些疑惑都解开了,写篇文章分享给大家,文章还算比较全面.当然可能有小宝鸽理解得不够深入透彻的地方,如果说得不正确还望指出. 看之前有必要跟某些猿友说一下,如果看一遍没有看明白呢,也没关系,当是了解一下,等真正使用到了,再回头看. 本文主要是将synchronized关键字用法作

Java多线程synchronized关键字

synchronized关键字代表着同步的意思,在Java中被synchronized修饰的有三种情况 1.同步代码块 //锁为objsynchronized(obj){ while(true){ if(product > 0){ System.out.println(Thread.currentThread().getName()+"消费:"+product--); } } } 2.同步函数 //锁为thispublic synchronized void consume()

Java中利用synchronized关键字实现多线程同步问题

Java 中多线程的同步依靠的是对象锁机制,synchronized关键字就是利用了封装对象锁来实现对共享资源的互斥访问. 下面以一个简单例子来说明多线程同步问题,我们希望在run()方法里加入synchronized关键字来实现互斥访问. package com.clark.thread; public class MyThread implements Runnable{     private int threadId;          public MyThread(int id){

多线程编程-- part 3 多线程同步->synchronized关键字

多线程同时访问一个资源,可以会产生不可预料的结果,所以为这个资源加锁,访问资源的第一个线程为其加锁后,其他线程便不能在使用那个资源,直到锁被解除. 举个例子: 存款1000元,能取出800的时候我就取800,当我同时用两个线程调用这个取钱操作时,有时可以取出1600元 static class HelloRunable implements Runnable{ private int money = 1000; //取出800元 int getMoney() { System.out.print

Java多线程(四)—— synchronized关键字续

1.synchronized原理 在java中,每一个对象有且仅有一个同步锁.这也意味着,同步锁是依赖于对象而存在.当我们调用某对象的synchronized方法时,就获取了该对象的同步锁.例如,synchronized(obj)就获取了“obj这个对象”的同步锁.不同线程对同步锁的访问是互斥的.也就是说,某时间点,对象的同步锁只能被一个线程获取到!通过同步锁,我们就能在多线程中,实现对“对象/方法”的互斥访问. 例如,现在有两个线程A和线程B,它们都会访问“对象obj的同步锁”.假设,在某一时

JAVA之旅(十三)——线程的安全性,synchronized关键字,多线程同步代码块,同步函数,同步函数的锁是this

JAVA之旅(十三)--线程的安全性,synchronized关键字,多线程同步代码块,同步函数,同步函数的锁是this 我们继续上个篇幅接着讲线程的知识点 一.线程的安全性 当我们开启四个窗口(线程)把票陆陆续续的卖完了之后,我们要反思一下,这里面有没有安全隐患呢?在实际情况中,这种事情我们是必须要去考虑安全问题的,那我们模拟一下错误 package com.lgl.hellojava; import javax.security.auth.callback.TextInputCallback

Java 多线程(六) synchronized关键字详解

Java 多线程(六) synchronized关键字详解 多线程的同步机制对资源进行加锁,使得在同一个时间,只有一个线程可以进行操作,同步用以解决多个线程同时访问时可能出现的问题. 同步机制可以使用synchronized关键字实现. 当synchronized关键字修饰一个方法的时候,该方法叫做同步方法. 当synchronized方法执行完或发生异常时,会自动释放锁. 下面通过一个例子来对synchronized关键字的用法进行解析. 1.是否使用synchronized关键字的不同 例子

Java多线程:synchronized关键字和Lock

一.synchronized synchronized关键字可以用于声明方法,也可以用来声明代码块,下面分别看一下具体的场景(摘抄自<大型网站系统与Java中间件实践>) 案例一:其中foo1和foo2是SynchronizedDemo1类的两个静态方法.在不同的线程中,这两个方法的调用是互斥的,不仅是它们之间,任何两个不同线程的调用也互斥. public class SynchronizedDemo1 { public synchronized static void foo1(){} pu

Java多线程系列--“基础篇”04之 synchronized关键字

概要 本章,会对synchronized关键字进行介绍.涉及到的内容包括:1. synchronized原理2. synchronized基本规则3. synchronized方法 和 synchronized代码块4. 实例锁 和 全局锁 转载请注明出处:http://www.cnblogs.com/skywang12345/p/3479202.html 1. synchronized原理 在java中,每一个对象有且仅有一个同步锁.这也意味着,同步锁是依赖于对象而存在.当我们调用某对象的sy