Synchronized 的使用

多线程程序可能经常遇到多个线程尝试访问相同资源并最终产生错误和无法预料的结果的情况。 

因此需要通过某种同步方法确保在给定时间点只有一个线程可以访问资源。Java 提供了一种使用同步块创建线程和同步它们的任务的方法。Java 中的同步块用 synchronized 关键字标记。Java 中的同步块在某个对象上同步。在同一个对象上同步的所有同步块一次只能在其中执行一个线程。所有其他试图进入同步块的线程都被阻塞,直到同步块内的线程退出该块。

synchronized(sync_object)
{
   // Access shared variables and other
   // shared resources
}

这种同步是在 Java 中通过一个称为监视器的概念实现的。在给定时间只有一个线程可以拥有一个监视器。当一个线程获得一个锁时,就说它已经进入了监视器。所有其他试图进入锁定监视器的线程都将被挂起,直到第一个线程退出监视器。

以下是带同步的多线程示例。

// A Java program to demonstrate working of
// synchronized.

import java.io.*;
import java.util.*;

// A Class used to send a message
class Sender
{
	public void send(String msg)
	{
		System.out.println("Sending\t" + msg );
		try
		{
			Thread.sleep(1000);
		}
		catch (Exception e)
		{
			System.out.println("Thread interrupted.");
		}
		System.out.println("\n" + msg + "Sent");
	}
}

// Class for send a message using Threads
class ThreadedSend extends Thread
{
	private String msg;
	Sender sender;

	// Receives a message object and a string
	// message to be sent
	ThreadedSend(String m, Sender obj)
	{
		msg = m;
		sender = obj;
	}

	public void run()
	{
		// Only one thread can send a message
		// at a time.
		synchronized(sender)
		{
			// synchronizing the send object
			sender.send(msg);
		}
	}
}

// Driver class
class SyncDemo
{
	public static void main(String args[])
	{
		Sender send = new Sender();
		ThreadedSend S1 =
			new ThreadedSend( " Hi " , send );
		ThreadedSend S2 =
			new ThreadedSend( " Bye " , send );

		// Start two threads of ThreadedSend type
		S1.start();
		S2.start();

		// wait for threads to end
		try
		{
			S1.join();
			S2.join();
		}
		catch(Exception e)
		{
			System.out.println("Interrupted");
		}
	}
}

 输出:

Sending     Hi 

 Hi Sent
Sending     Bye 

 Bye Sent

 

 在上面的例子中,我们选择在 ThreadedSend 类的 run() 方法中同步 Sender 对象。或者,我们可以将整个 send() 块定义为 synchronized 产生相同的结果。代码如下:

class Sender {
   public synchronized void send(String msg)
   {
       System.out.println("Sending\t" + msg);
       try {
           Thread.sleep(1000);
       }
       catch (Exception e) {
           System.out.println("Thread interrupted.");
       }
       System.out.println("\n" + msg + "Sent");
   }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值