码迷,mamicode.com
首页 > 编程语言 > 详细

Java线程同步操作

时间:2018-03-03 15:35:32      阅读:159      评论:0      收藏:0      [点我收藏+]

标签:++   pre   pos   new t   oid   code   count   tin   thread   

synchronized

作用于对象实例:对给定对象加锁,进入同步代码前要获得给定对象的锁。

作用于实例方法:相当于对当前实例加锁,进入同步代码前要获得当前实例的锁。

作用于静态方法:相当于对当前类加锁,进入同步代码前要获得当前类的锁。

使用

给实例对象加锁

public class AccountingSync implements Runnable {
    static AccountingSync instance = new AccountingSync();
    static int i = 0;

    @Override
    public void run() {
        for (int k = 0; k < 10000; k++) {
            synchronized (instance) {
                i++;
            }
        }
    }

    @Test
    public void testInteger() throws InterruptedException {
        int count = 10;
        Thread[] ts = new Thread[count];

        for (int k = 0; k < count; k++) {
            ts[k] = new Thread(instance);
        }

        // start
        for (int k = 0; k < count; k++) {
            ts[k].start();
        }

        // join
        for (int k = 0; k < count; k++) {
            ts[k].join();
        }

        System.out.println(i);
    }
}

给类方法加锁

public class AccountingSync2 implements Runnable {
    static AccountingSync2 instance = new AccountingSync2();
    static int i = 0;

    public synchronized void increase() {
        i++;
    }

    @Override
    public void run() {
        for (int k = 0; k < 10000; k++) {
            increase();
        }
    }

    @Test
    public void testInteger() throws InterruptedException {
        int count = 10;
        Thread[] ts = new Thread[count];

        for (int k = 0; k < count; k++) {
            ts[k] = new Thread(instance);
        }

        // start
        for (int k = 0; k < count; k++) {
            ts[k].start();
        }

        // join
        for (int k = 0; k < count; k++) {
            ts[k].join();
        }

        System.out.println(i);
    }
}

给类方法加锁的错误演示

public class AccountingSyncBad implements Runnable {
    static int i = 0;

    public synchronized void increase() {
        i++;
    }

    @Override
    public void run() {
        for (int k = 0; k < 10000; k++) {
            increase();
        }
    }

    @Test
    public void testInteger() throws InterruptedException {
        int count = 10;
        Thread[] ts = new Thread[count];

        for (int k = 0; k < count; k++) {
            ts[k] = new Thread(new AccountingSyncBad());
        }

        // start
        for (int k = 0; k < count; k++) {
            ts[k].start();
        }

        // join
        for (int k = 0; k < count; k++) {
            ts[k].join();
        }

        System.out.println(i);
    }
}

假设把给类实例加锁中的每个实例比作一个门,上面的测试方法中每个门都有锁但是10个门10把锁,每个线程进一个门。还是不能保证临界区资源i同时只一个线程访问

fix

@Test
public void testIntegerFix() throws InterruptedException {
  int count = 10;
  AccountingSyncBad instance = new AccountingSyncBad();
  Thread[] ts = new Thread[count];

  for (int k = 0; k < count; k++) {
    ts[k] = new Thread(instance);
  }

  // start
  for (int k = 0; k < count; k++) {
    ts[k].start();
  }

  // join
  for (int k = 0; k < count; k++) {
    ts[k].join();
  }

  System.out.println(i);
}

给静态类方法加锁

public class AccountingSyncClass implements Runnable {
    static int i = 0;

    public static synchronized void increase() {
        i++;
    }

    @Override
    public void run() {
        for (int k = 0; k < 10000; k++) {
            increase();
        }
    }

    @Test
    public void testInteger() throws InterruptedException {
        int count = 10;
        Thread[] ts = new Thread[count];

        for (int k = 0; k < count; k++) {
            ts[k] = new Thread(new AccountingSyncClass());
        }

        // start
        for (int k = 0; k < count; k++) {
            ts[k].start();
        }

        // join
        for (int k = 0; k < count; k++) {
            ts[k].join();
        }

        System.out.println(i);
    }
    
    @Test
    public void testIntegerFix() throws InterruptedException {
        int count = 10;
        AccountingSyncClass instance = new AccountingSyncClass();
        Thread[] ts = new Thread[count];

        for (int k = 0; k < count; k++) {
            ts[k] = new Thread(instance);
        }

        // start
        for (int k = 0; k < count; k++) {
            ts[k].start();
        }

        // join
        for (int k = 0; k < count; k++) {
            ts[k].join();
        }

        System.out.println(i);
    }
}

上面测试的testInteger方法和testIntegerFix方法都能得到正确的结果,原因是给静态类方法加锁相当于10个门用的同一把锁,保证了同一时间只有一个线程能访问临界区资源i。

Java线程同步操作

标签:++   pre   pos   new t   oid   code   count   tin   thread   

原文地址:https://www.cnblogs.com/okokabcd/p/8496417.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!