JAVA多线程之——同步与异步

时间:2021-08-11 18:36:51

线程的同步与异步
1.同步:synchronized.
同步从概念上来讲,就是一个资源的共享。因此在多线程环境中,重点就是共享,如果一个资源没有被共享,则不需要同步。
2.异步:asynchronized
异步就是在多线程环境中,多个线程可以同时访问某一个资源。而不需要竞争。相互独立。就像我们的ajax异步刷新。在刷新某个局部的时候,并不影响你进行其他操作。

Synchronized
对于JAVA对象而言,每个对象都有且仅有一个对象锁。不同的线程对于对象来说是互斥的。也就是说如果一个线程获取了某个对象的对象锁。那么其它线程就必须等待对象锁被释放之后,才能获取。一般而言,获取对象锁的情况有两种
1.当一个对象被synchronized锁住时,线程访问该对象会获取对象锁。如:synchronized(obj).
2.线程调用对象的被synchronized关键字修饰的非静态方法。 如:synchronized void method(){}.为什么是非静态方法呢?当一个静态方法被synchronized修饰的时候,那么线程访问该方法获取的是类锁。也就是说这个锁锁定的是整个类。而不是类的某个实例化对象。

synchronized的访问规则
1.多个线程同时访问被synchronized修饰的非静态方法活着代码块时,线程互斥。

public class ThreadTest2 {

public synchronized void method1() {
try {
for(int i = 0; i < 8; i++) {
Thread.currentThread().sleep(1000);
System.out.println(Thread.currentThread().getName() + ":" + i);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}

public void method2() {
for(int i = 0; i < 8; i++) {
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}
public static void main(String[] args) {

final ThreadTest2 test = new ThreadTest2();

Thread t1 = new Thread(new Runnable(){
@Override
public void run() {
test.method1();
}
});
Thread t2 = new Thread(new Runnable(){
@Override
public void run() {
test.method1();
}
});
t1.start();
t2.start();
}
}

2个线程同时访问加锁的方法时候运行结果:

Thread-0:0
Thread-0:1
Thread-0:2
Thread-0:3
Thread-0:4
Thread-0:5
Thread-0:6
Thread-0:7
Thread-1:0
Thread-1:1
Thread-1:2
Thread-1:3
Thread-1:4
Thread-1:5
Thread-1:6
Thread-1:7

2.一个个线程访问synchronized修饰的非静态方法。一个线程访问普通方法。异步。不互斥。

public class ThreadTest2 {

public synchronized void method1() {
try {
for(int i = 0; i < 8; i++) {
Thread.currentThread().sleep(1000);
System.out.println(Thread.currentThread().getName() + ":" + i);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}

public void method2() {
try {
for(int i = 0; i < 8; i++) {
Thread.currentThread().sleep(1000);
System.out.println(Thread.currentThread().getName() + ":" + i);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}


public static void main(String[] args) {

final ThreadTest2 test = new ThreadTest2();

Thread t1 = new Thread(new Runnable(){
@Override
public void run() {
test.method1();
}
});


Thread t2 = new Thread(new Runnable(){
@Override
public void run() {
test.method2();
}
});

t1.start();
t2.start();

}



}

运行结果:

Thread-1:0
Thread-0:0
Thread-1:1
Thread-0:1
Thread-1:2
Thread-0:2
Thread-0:3
Thread-1:3
Thread-1:4
Thread-0:4
Thread-1:5
Thread-0:5
Thread-0:6
Thread-1:6
Thread-1:7
Thread-0:7

3.一个线程获对象锁,一个线程获取类锁。不互斥

public class ThreadTest2 {

public synchronized void method1() {
try {
for(int i = 0; i < 8; i++) {
Thread.currentThread().sleep(1000);
System.out.println(Thread.currentThread().getName() + ":" + i);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}

public synchronized static void method2() {
try {
for(int i = 0; i < 8; i++) {
Thread.currentThread().sleep(1000);
System.out.println(Thread.currentThread().getName() + ":" + i);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}


public static void main(String[] args) {

final ThreadTest2 test = new ThreadTest2();

Thread t1 = new Thread(new Runnable(){
@Override
public void run() {
test.method1();
}
});


Thread t2 = new Thread(new Runnable(){
@Override
public void run() {
test.method2();
}
});

t1.start();
t2.start();

}
}

运行结果:

Thread-1:0
Thread-0:0
Thread-1:1
Thread-0:1
Thread-1:2
Thread-0:2
Thread-1:3
Thread-0:3
Thread-1:4
Thread-0:4
Thread-1:5
Thread-0:5
Thread-1:6
Thread-0:6
Thread-0:7
Thread-1:7