Java多线程同步 – synchronized 用法

1.      利用类对象进行同步

当两个线程访问同一个类对象时,发生竞争。同步加锁的是对象,而不是代码。

package thrds;

public class FiveThread {

	public static void main(String args[])
	{
		ThTst obj = new ThTst();
		Thread t1 = new Thread(obj);  // 两个线程用同一个对象,发生互斥(属于对象互斥)
		Thread t2 = new Thread(obj);

		t1.start();
		t2.start();
	}

}

class ThTst extends Thread {

	public void run() {
		tst();
	}

	synchronized void tst()
	{
		System.out.println(Thread.currentThread().getId() + " in");

		try {
			Thread.sleep(5000);
		} catch (InterruptedException e) {
					e.printStackTrace();
		}

		System.out.println(Thread.currentThread().getId() + " out");
	}
}

输出结果:
15 in
15 out
14 in
14 out

如果将上述 main函数中改为:
Thread t1 = new Thread(new ThTst());  // 使用两个对象,不会发生竞争
Thread t2 = new Thread(new ThTst());

输出结果:
17 in
15 in
15 out
17 out

2.      使用类定义和 对象 进行同步(类.class)

即使两个线程分别访问不同的对象,也会发生竞争。加锁的是代码段。

因为一个类的类定义只有一个,因此,到加锁的地方,只能有一个线程进去执行。

注意:null不可用来作为同步对象。

package thrds;

public class SixThread {

	public static void main(String args[])
	{
		Thread t1 = new Thread(new ThTst2());
		Thread t2 = new Thread(new ThTst2());

		t1.start();
		t2.start();
	}

}

class ThTst2 extends Thread {

	private static Integer iObj = 9;

	public void run() {
		tst();
	}

	synchronized void tst()
	{
		synchronized (ThTst2.class) { //这里可用任何类类型,如 String.class, Integer.class  或使用 其他对象如iObj 也是一样的

			System.out.println(Thread.currentThread().getId() + " in");

			try {
				Thread.sleep(5000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}

			System.out.println(Thread.currentThread().getId() + " out");
		}
	}
}

输出结果:
14 in
14 out
16 in
16 out

3.      2中使用对象同步,用来同步的对象,可由参数传入。这样,可提供更多的灵活性,程序员可以控制哪几个线程竞争同一个对象。(在设计时可参考)

package thrds;

import org.omg.CORBA.INV_OBJREF;

public class SevenThread {

	public static void main(String args[])
	{
		ThTst3 tObj1 = new ThTst3();
		ThTst3 tObj2 = new ThTst3();

		String lock = new String("lock");
		tObj1.setLock(lock);
		tObj2.setLock(lock);

		Thread t1 = new Thread(tObj1);
		Thread t2 = new Thread(tObj2);

		t1.start();
		t2.start();
	}

}

class ThTst3 extends Thread {

	private String lock = null;

	@Override
	public void run() {
		tst();
	}

	synchronized void tst()
	{
		synchronized (lock) { //同步对象由参数传入

			System.out.println(Thread.currentThread().getId() + " in");

			try {
				Thread.sleep(5000);
			} catch (InterruptedException e) {
				// TODO 自动生成的 catch 块
				e.printStackTrace();
			}

			System.out.println(Thread.currentThread().getId() + " out");
		}
	}

	void setLock(String lock)
	{
		this.lock = lock;
	}
}

输出结果:
15 in
15 out
16 in
16 out

synchronized关键字,多线程在同步时,需要看用来同步的对象(包括类定义)是不是唯一的。只有对象是唯一的时候,才会发生互斥。

时间: 2024-10-13 02:06:18

Java多线程同步 – synchronized 用法的相关文章

Java多线程-同步:synchronized 和线程通信:生产者消费者模式

大家伙周末愉快,小乐又来给大家献上技术大餐.上次是说到了Java多线程的创建和状态|乐字节,接下来,我们再来接着说Java多线程-同步:synchronized 和线程通信:生产者消费者模式. 一.同步:synchronized 多个线程同时访问一个对象,可能造成非线程安全,数据可能错误,所谓同步:就是控制多个线程同时访就是控制多线程操作同一个对象时,注意是同一个对象,数据的准确性, 确保数据安全,但是加入同步后因为需要等待,所以效率相对低下. 如:一个苹果,自己一个人去咬怎么都不会出问题,但是

Java多线程同步 synchronized 关键字的使用

代表这个方法加锁,相当于不管哪一个线程A每次运行到这个方法时,都要检查有没有其它正在用这个方法的线程B(或者C D等),有的话要等正在使用这个方法的线程B(或者C D)运行完这个方法后再运行此线程A,没有的话,直接运行它包括两种用法:synchronized 方法和 synchronized 块. JAVA多线程买票案例 synchronized 同步 用synchronized 块实现同步 public static void main(String[] args) { // runable对

转:关于JAVA多线程同步

转:http://lanvis.blog.163.com/blog/static/26982162009798422547/ 因为需要,最近关注了一下JAVA多线程同步问题.JAVA多线程同步主要依赖于若干方法和关键字.将心得记录如下: 1  wait方法:        该方法属于Object的方法,wait方法的作用是使得当前调用wait方法所在部分(代码块)的线程停止执行,并释放当前获得的调用wait所在的代码块的锁,并在其他线程调用notify或者notifyAll方法时恢复到竞争锁状态

java基础知识回顾之java Thread类学习(六)--java多线程同步函数用的锁

1.验证同步函数使用的锁----普通方法使用的锁 思路:创建两个线程,同时操作同一个资源,还是用卖票的例子来验证.创建好两个线程t1,t2,t1线程走同步代码块操作tickets,t2,线程走同步函数封装的代码操作tickets,同步代码块中的锁我们可以指定.假设我们事先不知道同步函数用的是什么锁:如果在同步代码块中指定的某个锁(测试)和同步函数用的锁相同,就不会出现线程安全问题,如果锁不相同,就会发生线程安全问题. 看下面的代码:t1线程用的同步锁是obj,t2线程在操作同步函数的资源,假设不

java基础之synchronized用法

首先,参考文章:http://www.cnblogs.com/devinzhang/archive/2011/12/14/2287675.html PS:参考文章很长,但内容非常丰富,若是初学者,更要有耐心读完. 第二,个人小结: 关于synchronized关键字的作用: 1.在某个对象的所有synchronized方法中,在某一时刻,只能有一个唯一的一个线程去访问这些synchronized方法 2.如果一个方法是synchronized方法,那么该synchronized关键字表示给当前对

java多线程中join用法

thread.Join把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程.比如在线程B中调用了线程A的Join()方法,直到线程A执行完毕后,才会继续执行线程B. package com.wzs; /** * Java多线程中join用法 * * @author Administrator * */ public class JoinTest { public static void main(String[] args) { BThread bThread = new B

四、java多线程核心技术——synchronized同步方法与synchronized同步快

一.synchronized同步方法 论:"线程安全"与"非线程安全"是多线程的经典问题.synchronized()方法就是解决非线程安全的. 1.方法内的变量为线程安全 public void addI(String username) { try { int num = 0; \\方法内的变量为线程安全 if (username.equals("a")) { num = 100; System.out.println("a set

java多线程——同步块synchronized详解

Java 同步块(synchronized block)用来标记方法或者代码块是同步的.Java同步块用来避免竞争.本文介绍以下内容: Java同步关键字(synchronzied) 实例方法同步 静态方法同步 实例方法中同步块 静态方法中同步块 Java同步示例 Java 同步关键字(synchronized) Java中的同步块用synchronized标记.同步块在Java中是同步在某个对象上.所有同步在一个对象上的同步块在同时只能被一个线程进入并执行操作.所有其他等待进入该同步块的线程将

Java多线程同步的方法

一 synchronized关键字 1.synchronized实现原理: ---基于对象监视器(锁) java中所有对象都自动含有单一的锁,JVM负责跟踪对象被加锁的次数.如果一个对象被解锁,其计数变为0.在任务(线程)第一次给对象加锁的时候, 计数变为1.每当这个相同的任务(线程)在此对象上获得锁时,计数会递增.只有首先获得锁的任务(线程)才能继续获取该对象上的多个锁.每当任务离开时,计数递减,当计数为0的时候,锁被完全释放. Java中每个对象或者类都有一把锁与之相关联,对于对象来说,监视