为确保多线程的正确执行,引入同步的概念。
1、synchronized方法和块
/**
* 讲了同步方法和同步块的用法
* 同步类方法、同步成员方法、非同步方法之间可异步执行。
*/
public class Type {
static Type type;
public static void main(String[] args) {
type = new Type();
/*new Thread(){
@Override
public void run() {
type.method1();
super.run();
}
}.start();
new Thread(){
@Override
public void run() {
type.method2();
super.run();
}
}.start();
new Thread(){
@Override
public void run() {
Type.method3();
super.run();
}
}.start();
new Thread(){
@Override
public void run() {
Type.method4();
super.run();
}
}.start();*/
new Thread(){
@Override
public void run() {
//用来锁住某一代码块
synchronized(type){
System.out.println("同步块1");
try {
Thread.sleep(5000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
super.run();
}
}.start();
new Thread(){
@Override
public void run() {
//等待其他线程释放锁
synchronized(type){
System.out.println("同步块2");
try {
Thread.sleep(5000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
super.run();
}
}.start();
type.method6();
/*new Thread(){
public void run() {
type.method5();
};
}.start();*/
}
public synchronized void method1(){
System.out.println("method1-start");
try {
Thread.sleep(5000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("method1-end");
}
public synchronized void method2(){
System.out.println("method2-start");
try {
Thread.sleep(5000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("method2-end");
}
public synchronized static void method3(){
System.out.println("method3-start");
try {
Thread.sleep(5000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("method3-end");
}
public synchronized static void method4(){
System.out.println("method4-start");
try {
Thread.sleep(5000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("method4-end");
}
//当前线程获得锁,锁的对象是Type实例。所以该方法执行完线程释放锁之前,其他线程无法获得锁。
public synchronized void method5(){
System.out.println("method5-start");
//method1和method5在同一线程执行
method1();
System.out.println("method5-end");
}
public void method6(){
System.out.println("method6");
}
}
2、ReentrantReadWriteLock用来实现多线程的同步,下面介绍它的用法。
public class LockTest {
//ReentrantLock实现Lock和Serializable接口
//实现Serializable和ReadWriteLock接口
private ReentrantReadWriteLock mLock;
private String name;
public LockTest(){
//create ReadLock and WriteLock
mLock = new ReentrantReadWriteLock(false);
}
public void setName(String name){
//ReentrantReadWriteLock.WriteLock/ReadLock 接口Lock的子类
mLock.writeLock().lock();
try{
Thread.sleep(3000);
this.name = name;
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
mLock.writeLock().unlock();
}
}
public String getName(int time){
mLock.readLock().lock();
try {
Thread.sleep(time);
return name+"-"+new Random().nextInt(32);
} catch (InterruptedException e) {
e.printStackTrace();
return name;
}finally{
mLock.readLock().unlock();
}
}
/**WriteLock降级为ReadLock*/
public void execute(){
mLock.writeLock().lock();
//type some code about write
mLock.readLock().lock();
mLock.writeLock().unlock();
//type some code about read
mLock.readLock().unlock();
}
public static void main(String[] args) {
final LockTest lockTest = new LockTest();
lockTest.execute();
new Thread("Thread-0"){
public void run() {
System.out.println(Thread.currentThread().getName()+"|"+lockTest.getName(3000));
};
}.start();
new Thread("Thread-1"){
public void run() {
lockTest.setName("Google");
System.out.println(Thread.currentThread().getName()+"|"+lockTest.getName(3000));
};
}.start();
}
}