同步和锁

来源:互联网 发布:php 开源社区系统 编辑:程序博客网 时间:2024/06/07 11:10

多线程的安全的原因
1.多个线程在操作共享的数据
2.操作共享数据的代码有多条
当一个线程再行操作共享数据的多条语句,其他线程参与了运算

问题:
在一个程序中有一个数据被多条线程所操作,导致结果出错如何避免(不同步)
示例代码:

public class Text_Thread{    public static void main(String[] args)    {    TicketOfRunnable t1 = new TicketOfRunnable();    TicketOfRunnable t2 = new TicketOfRunnable();    Thread a = new Thread(t1);    Thread b = new Thread(t1);     Thread c = new Thread(t1);    Thread d = new Thread(t1);   //定义四个线程类的对象,    a.start();    b.start();    c.start();    d.start();   //将四个线程对象开启    }}class TicketOfRunnable implements Runnable{    private int IDnumber = 5;    public void run()     {        while(true)        {              if(IDnumber > 0)              {                 try                 {                    Thread.sleep(10);//让线程休眠一小会                 }                 catch (InterruptedException e)                  {}                //让线程休眠的目的是降低不同的线程切换的速度                  System.out.println(Thread.currentThread().getName()+"...."+IDnumber--);              }        }    }}

运行结果:

Thread-0….4
Thread-1….5
Thread-3….2
Thread-2….3
Thread-1….0
Thread-2….1
Thread-3….-1
Thread-0….-2

//出现了小于等于0的结果

解决方法:
将多条共享数据的代码封装起来,当有线程在执行这些代码的时候,其他线程不能进入,执行完毕之后,其他线程才能参与运算
关键字
synchronized(obj) //这个代码块是有参数的(对象)
{ 所要封装的代码块 }
示例代码:

public class Text_Thread{    public static void main(String[] args)    {    TicketOfRunnable t1 = new TicketOfRunnable();    TicketOfRunnable t2 = new TicketOfRunnable();    Thread a = new Thread(t1);    Thread b = new Thread(t1);      Thread c = new Thread(t1);    Thread d = new Thread(t1);    a.start();      b.start();    c.start();    d.start();      }}class TicketOfRunnable implements Runnable{    private int IDnumber = 5;    Object obj = new Object();    public void run()     {        while(true)        {            synchronized(obj)            {              if(IDnumber > 0)              {                 try                 {                    Thread.sleep(10);//让线程休眠一小会                 }                  catch (InterruptedException e)                   {}                 System.out.println(Thread.currentThread().getName()+"...."+IDnumber--);              }            }        }    }}

运行结果:

运行结果:
Thread-0….5
Thread-2….4
Thread-2….3
Thread-2….2
Thread-2….1

1.如果即使使用了同步锁还是没有解决问题考虑下面的问题
同步的前提:必须有多个线程使用同一个锁
一把对象锁的实现:

class TicketOfRunnable implements Runnable{    private int IDnumber = 5;    Object obj = new Object();  //只创建一次这个对象    public void run()     {        while(true)        {            synchronized(obj)            {              。。。。。。         }       }    } //正确可以确保同步

错误的使用多把对象锁示例:

class TicketOfRunnable implements Runnable{    private int IDnumber = 5;    public void run()     {      Object obj = new Object();//随着线程的进入都要进行对象创建(相当于多锁)        while(true)        {            synchronized(obj)            {              ....         }      }   }

2.同步函数
关键字synthrontic直接放在函数的关键字中

public synchronized void add(int num) //同步函数

同步函数的锁
功能也是实现同步,但是同步函数的锁与同步代码块的锁不是同一个锁,同步函数的锁就是在创建线程是传入的对象(this)
示例代码:

public class SynFunctionLockDemo{    public static void main(String[] args)    {        TicketOfRunnable t1 = new TicketOfRunnable();        Thread a1 = new Thread(t1);        Thread a2 = new Thread(t1);        a1.start();        try{Thread.sleep(10);}  catch(InterruptedException e) {}  //让主线程进入睡眠        t1.FLAG = false;        a2.start();    }}

3.静态同步方法(锁)
静态函数直接就加载进方法区是字节码文件对象(getClass)
获取字节码文件对象:
Class clazz = TicketOfRunnable.class
//获取字节码文件的对象
class calzz = t1.getClass();
//创建了对象以后来获取字节码文件对象

介绍一种可以切换同步代码块与同步函数的方法
示例代码:

class TicketOfRunnable implements Runnable{    private int IDnumber = 5;    Object obj = new Object();    boolean FLAG = true;    public void run()    {        if(FLAG)        {            while(true)            {                synchronized(obj)                {                    fun("同步代码块");                }            }        }        else        {            while(true)                show();        }    }    public synchronized void show()    {        fun("同步函数");    }    //将原来的代码中重复的部分进行抽取,用函数封装起来

运行结果:

Thread-0….同步代码块5
Thread-0….同步代码块4
Thread-1….同步函数4
Thread-1….同步函数3
Thread-0….同步代码块3
Thread-1….同步函数2
Thread-0….同步代码块2
Thread-1….同步函数1
Thread-0….同步代码块1

原创粉丝点击