您的位置:首页 > 编程语言 > Java开发

Java线程同步操作

2018-03-03 00:00 417 查看
摘要: Java线程同步操作

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
7fe0
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 线程