JAVA并发:多线程编程之同步代码块与同步函数(二)

【4】多线程的同步的两种方法

  • 线程同步:程序中不能有多个线程同时在一段代码之间执行。
  • 多线程的同步的两种方法:同步代码块、同步函数。
【4-1】同步代码块
  • 为解决【3-1】中的问题,一种方法是保证以下代码的原子性。
if (Numbe > 0)
{
         System.out.println(Thread.currentThread().getName() +" is saling ticket "+ Numbe--);
}
synchronized(str)
{
    if (Numbe > 0)
    {       System.out.println(Thread.currentThread().getName() +" is saling ticket "+ Numbe--);
    }
}
  • synchronized语句的格式为:

    synchronized(object){代码段}

  • object可以是任意的对象,例如,String str = new String("");至于为什么可以是任意对象,可查阅:http://www.cnblogs.com/ygj0930/p/6561667.html 。此网址的内容描述如下:
    这里写图片描述

  • 修改代码3,得到代码4:

/*代码4*/
class TestThread implements Runnable
{
    private int Numbe = 10;
    String str = new String("");
    public void run()
    {
        while(true)
        {
            synchronized(str)
            {
                if (Numbe > 0)
                {
                  try
                {
                    Thread.sleep(10);
                }
                  catch (Exception e)
                {
                    System.out.println(e.getMessage());
                }
                System.out.println(Thread.currentThread().getName() +" is saling ticket "+ Numbe--);
                }
            }

        }
    }
}
  • 编译、运行:问题已被解决。
    这里写图片描述
【4-2】同步函数
  • 同步函数实现线程间的同步是,只要在需要同步的函数定义钱加上synchronized关键字即可。
/*代码5*/
class TestThread implements Runnable
{
    private int Numbe = 10;
    public void run()
    {
        while(true)
        {
            sale();
        }
    }
    public synchronized void sale()
    {
        if (Numbe > 0)
                {
                  try
                {
                    Thread.sleep(10);
                }
                  catch (Exception e)
                {
                    System.out.println(e.getMessage());
                }
                System.out.println(Thread.currentThread().getName() +" is saling ticket "+ Numbe--);
                }
    }
}
  • 编译、运行
    这里写图片描述
  • 这里写图片描述
【4-3】代码块与函数间的同步
  • 要实现代码块与函数间的同步,就必须要让代码块与函数使用同一个监视器对象。
  • 在同步代码块中,synchronized的监视器对象可以是任意的。
  • 然而,同步代码块要与函数间同步,synchronized的监视器对象就不能是任意的,同步函数所用的监视器对象只能是this【类中的非静态方法始终能访问到的一个对象就是这个对象本身,即this】。因此,要实现代码块与函数间的同步,同步代码块中的synchronized的监视器对象只能是this。
  • 以《JAVA就业培训教程》中p196-197的代码为例:
package mydemo;
class TestThread implements Runnable
{
    private int Numbe = 10;
    String str = new String("");
    public void run()
    {
        if (str.equals("method"))
        {
            while(true)
            {
                sale();
            }
        }
        else
        {
            synchronized(this)
            {
            if (Numbe > 0)
            {
                  try
                {
                    Thread.sleep(10);
                }
                  catch (Exception e)
                {
                    System.out.println(e.getMessage());
                }
                System.out.println( "同步代码块"+" is saling ticket "+ Numbe--);
             }
        }

        }

    }
    public synchronized void sale()
    {
        if (Numbe > 0)
                {
                  try
                {
                    Thread.sleep(10);
                }
                  catch (Exception e)
                {
                    System.out.println(e.getMessage());
                }
                System.out.println("同步函数"+" is saling ticket "+ Numbe--);
                }
    }
}
public class ThreadDemo
{
    public static void main(String[] args)
    {
        TestThread tDemo = new TestThread();
        new Thread(tDemo).start();
        try{Thread.sleep(1);}catch (Exception e){}
        tDemo.str = new String("method");
        new Thread(tDemo).start();
    }
}
  • 编译、运行:
    这里写图片描述
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值