Java线程同步

本文深入探讨了Java线程同步的实现方式,包括通过继承Thread类、实现Runnable接口及使用synchronized关键字。同时介绍了Java线程同步的关键方法:wait、notify、notifyAll,以及它们在多线程环境下如何确保数据一致性。
摘要由CSDN通过智能技术生成

在说线程同步之前,先简单的提一下Java线程方面的知识:Java里的多线程是通过java.lang.Thread类来实现的,每个线程都拥有自己独立的方法栈空间,Java中实现多线程主要有以下方法:

1、继承Thread类,并实现run方法。 

        public class myTheard extends Thread{

                    public void run(){

                          System.Out.println("线程执行");

}

启动方法:myTheard thread = new myTheard ();

                    thread .start();

2、实现Runnable接口。

        public class myTheard implements Runnable{

                     public void run(){

                          System.Out.println("线程执行");

}

}

为了启动该线程,首先需要实例化一个Thread对象,并传入自己的myTread实例。

         myThread mythread = new myThread ();

         Thread thread = new Thread(mythread);

          thread.start();

该过程实际过程为:将mythread对象传入thread后,接着便调用了mythread的run方法。

 

下面介绍Java线程同步相关事宜:

Java多线程同步实际上主要依赖于若干方法和关键字:包括wait、notify、notifyAll、synchronized等。

一、synchronized

在Java中每个对象都有一个内置锁,当程序运行到非静态的synchronized同步方法上时,自动获得与正在执行代码类的当前实例(this实例)有关的锁。注意:只有当程序运行到synchronized 同步方法或代码块时该对象锁才起作用,一个对象只有一个锁。所以,如果一个线程获得该锁,就没有其他线程可以获得锁,直到第一个线程释放(或返回)锁。这也意味着任何其他线程都不能进入该对象上的synchronized方法或代码块,直到该锁被释放。释放锁是指持锁线程退出了synchronized 同步方法或代码块,另外值得注意的是,synchronized只能同步方法,而不能同步变量和类。

synchronized可以有下面两种写法(非静态方法),效果相同。

          public synchronized int getX() {
                      return x++;
}


          public int getX() {
                      synchronized (this) {
                                 return x++;
}
}

如果要同步静态方法,则需要一个用于整个类对象的锁,这个对象就是这个类(xxx.class)。以下两个例子效果相同。

           public static synchronized int setName(String name){
                       xxx.name = name;
}


           public static int setName(String name){
                       synchronized(Xxx.class){
                                xxx.name = name;
}
}

如果线程试图进入同步方法,而其锁已经被占用,则线程在该对象上被阻塞。实质上,线程进入该对象的的一种池中,必须在那里等待,直到其锁被释放,该线程再次变为可运行或运行位置。

二、wait

wait()允许我们将线程置入“睡眠”状态",也就是说,wait也是让当前线程阻塞的,这一点和sleep或者suspend是相同的。而wait和sleep、suspend的区别在于当执行wait方法后,如果当前代码块持有对象锁,那么此时该线程会暂时让出该锁,让其他的线程先执行,等到其他线程执行完后(当其他线程调用notify或notifyAll后)才继续执行该代码块。这意味着可在执行wait期间调用线程对象中的其他同步方法,而这对于sleep和suspend是不可能的。 但是注意我前面说的,只是暂时放弃对象锁,暂时给其它线程使用,wait所在的线程还是要把这个对象锁收回来的,wait嘛,就是wait别人用完了还给我呗。那怎么把对象锁收回来呢?
   第一种方法,限定借出去的时间。在wait()中设置参数,比如wait(1000),以毫秒为单位,就表明只借出去1秒中,一秒钟之后,自动收回。
   第二种方法,让借出去的主动通知,对方用完了,要还给我了,这时,我马上就收回来,那么别人怎么通知我呢?当然是notify()了,只有在一个notify()或notifyAll()发生变化的时候,线程才会被唤醒。 因此,我们可将一个wait()和notify()置入任何同步方法或同步块内部,无论在那个类里是否准备进行涉及线程的处理。而且实际上,我们也只能在同步方法或者同步块里面调用wait()和notify()。

三、notify、notifyAll

这两个方法已经在wait中阐明意思了,这里就不再罗嗦了

 

好了,关于Java线程同步暂时只了解这些,将来有新发现再补充吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值