@huangyichun
2017-08-30T16:09:10.000000Z
字数 3979
阅读 795
多线程
本文主要介绍在多线程中对于普通方法和静态方法加锁调用产生的情况。
结论:
下面主要是验证这两个结论:
class Number{
public synchronized void getOne() {
System.out.println("one");
}
public synchronized void getTwo(){
System.out.println("two");
}
}
public static void main(String[] args) {
Number number = new Number();
new Thread(new Runnable() {
@Override
public void run() {
number.getOne();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
number.getTwo();
}
}).start();
}
运行结果为:
one
two
public synchronized void getOne() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("one");
}
运行结果为:
one
two
说明了两个方法调用的是同一个锁,锁先被线程一调用了,导致线程二处于等待状态,当线程一执行完后,线程二才能继续执行
public class TestThread8Monitor {
public static void main(String[] args) {
Number number = new Number();
new Thread(new Runnable() {
@Override
public void run() {
number.getOne();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
number.getTwo();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
number.getThree();
}
}).start();
}
}
class Number{
public synchronized void getOne() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("one");
}
public synchronized void getTwo(){
System.out.println("two");
}
public void getThree(){//普通未加锁方法
System.out.println("three");
}
}
运行结果:
three
one
two
说明:普通方法不受线程锁的影响,线程三直接执行,无须等待前面的线程释放锁
public class TestThread8Monitor {
public static void main(String[] args) {
Number number = new Number();
Number number2 = new Number();
new Thread(new Runnable() {
@Override
public void run() {
number.getOne();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
number2.getTwo();
}
}).start();
}
}
class Number{
public synchronized void getOne() {
try {
Thread.sleep(3000);//等待3秒
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("one");
}
public synchronized void getTwo(){
System.out.println("two");
}
}
运行结果: two one
说明:调用加锁的普通方法,上锁的是this,也就是该对象,因此两个线程分别调用两个不同的对象,两者之间不存在互斥等待问题。
public class TestThread8Monitor {
public static void main(String[] args) {
Number number = new Number();
new Thread(new Runnable() {
@Override
public void run() {
number.getOne();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
number.getTwo();
}
}).start();
}
}
class Number{
public static synchronized void getOne() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("one");
}
public synchronized void getTwo(){
System.out.println("two");
}
}
运行结果: two one
说明: 静态方法锁和普通方法锁的目标不同。
public class TestThread8Monitor {
public static void main(String[] args) {
Number number = new Number();
Number number2 = new Number();
new Thread(new Runnable() {
@Override
public void run() {
number.getOne();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
number2.getTwo();
}
}).start();
}
}
class Number{
public static synchronized void getOne() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("one");
}
public static synchronized void getTwo(){
System.out.println("two");
}
}
运行结果: one two
说明:静态方法加锁是在类上的,也就是类的Class实例。因此两个线程调用两个对象的不同方法,结果却需要互斥调用
//非公平锁
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
if (compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
//公平锁
protected final boolean tryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
if (!hasQueuedPredecessors() &&
compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0)
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}