18.synchronized

同步的前提:

  1. 必须要有两个或者两个以上的线程
  2. 必须是多个线程使用同一个锁
  3. 必须保证同步中只能有一个线程在运行
  • 好处:解决了多线程的安全问题
  • 弊端:多个线程需要判断锁,较为消耗资源、抢锁的资源。
import java.util.ArrayList;
import java.util.List;

/**
 * synchronized 实现线程间的同步,对同步的代码加锁,似的每次只能有一个线程进入同步块
 * 可以保证线程间的可见性和有序性
 * · 指定加锁对象:对给定对象加锁,进入同步代码前要获取给定对象的锁
 * · 直接作用于实例方法:相当于对当前实例加锁,进入同步代码前要获取当前实例的锁
 * · 直接作用于静态方法:相当于对当前类加锁,进入同步代码前要获取当前类的锁 -- class文件
 */
public class SynchronizedDemo {
    private static int size = 0;
    private static List<Integer> arrayOne = new ArrayList<>(10000);
    private static List<Integer> arrayTwo = new ArrayList<>(10000);
    public static synchronized void increase(){ //synchronized作用于一个实例方法
        size++;
    }
    public static void main(String[] args) throws InterruptedException{

        for (int i = 0; i < 10000; i++) {
            arrayOne.add(0);
            arrayTwo.add(0);
        }
        Thread threadOne = new Thread(() -> {
            int length = arrayOne.size();
            for (int i = 0; i < length; i++) {
                if (arrayOne.get(i).intValue()==0){
                    increase();
                }
            }
        });
        Thread threadTwo = new Thread(() -> {
            int length = arrayTwo.size();
            for (int i = 0; i < length; i++) {
                if (arrayTwo.get(i).intValue()==0){
                    increase();
                }
            }
        });
        threadOne.start();
        threadTwo.start();
        threadOne.join();
        threadTwo.join();
        System.out.println(size);
    }
}

import java.util.ArrayList;
import java.util.List;

/**
 * Runnable
 */
public class SynchronizedDemo1 {
    private static int size = 0;
    private static List<Integer> arrayOne = new ArrayList<>(10000);
    private static List<Integer> arrayTwo = new ArrayList<>(10000);

    public static class AccountSyncBad implements Runnable{
        synchronized void increase(){ //synchronized
            size++;
        }
        @Override
        public void run() {
            int length = arrayOne.size();
            for (int i = 0; i < length; i++) {
                if (arrayOne.get(i).intValue()==0){
                    increase();
                }
            }
        }
    }
    public static void main(String[] args) throws InterruptedException{
        for (int i = 0; i < 10000; i++) {
            arrayOne.add(0);
            arrayTwo.add(0);
        }
        AccountSyncBad accountSyncBad = new AccountSyncBad();
        Thread threadOne = new Thread(accountSyncBad);
        Thread threadTwo = new Thread(accountSyncBad);
        threadOne.start();
        threadTwo.start();
        threadOne.join();
        threadTwo.join();
        System.out.println(size);
    }
}

import java.util.ArrayList;
import java.util.List;

/**
 * 两个线程指向不同的Runnable实例,这两个线程使用的是两把不同的锁,无法保证线程安全
 */
public class SynchronizedDemo2 {
    private static int size = 0;
    private static List<Integer> arrayOne = new ArrayList<>(10000);
    private static List<Integer> arrayTwo = new ArrayList<>(10000);

    public static class AccountSyncBad implements Runnable{
        synchronized void increase(){ //synchronized
            size++;
        }
//        static synchronized void increase(){ //修改为static,这样即使两个线程指向不同的Runnable,但请求的是当前类的锁,因此可以正确同步
//            size++;
//        }
        @Override
        public void run() {
            int length = arrayOne.size();
            for (int i = 0; i < length; i++) {
                if (arrayOne.get(i).intValue()==0){
                    increase();
                }
            }
        }
    }
    public static void main(String[] args) throws InterruptedException{
        for (int i = 0; i < 10000; i++) {
            arrayOne.add(0);
            arrayTwo.add(0);
        }
        Thread threadOne = new Thread(new AccountSyncBad());
        Thread threadTwo = new Thread(new AccountSyncBad());
        threadOne.start();
        threadTwo.start();
        threadOne.join();
        threadTwo.join();
        System.out.println(size);
    }
}
posted @ 2019-08-20 17:22  fly_bk  阅读(136)  评论(0编辑  收藏  举报