多线程与高并发(三)synchronized关键字

上一篇中学习了线程安全相关的知识,知道了线程安全问题主要来自JMM的设计,集中在主内存和线程的工作内存而导致的内存可见性问题,及重排序导致的问题。上一篇也提到共享数据会出现可见性和竞争现象,如果多线程间没有共享的数据也就是说多线程间并没有协作完成一件事情,那么,多线程就不能发挥优势,不能带来巨大的价值。而共享数据如何处理,一个很简单的想法就是依次去读写共享变量,这样就能保证读写的数据是最新的,就不会出现数据安全性问题,java中我们使用synchronized关键字去做让每个线程依次排队操作共享变量的功能。很明显这样做效率不高,但是这是基础。

一、使用synchronized

我们从使用开始学习,synchronized是一个关键字,在我们需要进行同步处理的地方加上synchronized即可。

分类   具体分类   被锁对象   伪代码  
方法   实例方法   类的实例对象   public synchronized void method(){}  
静态方法   类对象   public static synchronized void method(){}  
代码块   实例对象   类的实例对象   synchronized(this){}  
class对象   类对象   synchronized(Demo.class){}  
任意实例对象的Object   实例对象Object   String lock="";synchronized(lock){}  

synchronized可以用在方法上也可以使用在代码块中,其中方法是实例方法和静态方法分别锁的是该类的实例对象和该类的对象。而使用在代码块中也可以分为三种,具体的可以看上面的表格。这里的需要注意的是:如果锁的是类对象的话,尽管new多个实例对象,但他们仍然是属于同一个类依然会被锁住,即线程之间保证同步关系

1.1 同步方法

先看下下面这段代码:

public class SynchronizedDemo1 { private int count; public void countAdd() { for (int i = 0; i < 5; i++) { try { System.out.println(Thread.currentThread().getName() + ":" + (count++)); Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } public static void main(String[] args) { SynchronizedDemo1 demo1 = new SynchronizedDemo1(); new Thread(new Runnable() { @Override public void run() { demo1.countAdd(); } }).start(); new Thread(new Runnable() { @Override public void run() { demo1.countAdd(); } }).start(); } }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpwfgp.html