1.用static 修饰的方法再加上sychonized 相当于是一个类锁,类名加方法名就能访问这个方法
对象锁,是指只有那个对象加上方法名才能访问的
2.同步通信和异步通信的区别
同步:我叫你吃饭,你若暂时有事情我就一直在那等,不干别的事情,直到你忙完。
异步:我叫你吃饭,你若暂时有事情,我就先撤,干点别的,你忙完了再通过某种方式,如电话,通知我。
这两者没有什么好不好之分,适用场景决定方式,简单举例来首,如果是IO密集型的,可能会用同步IO,否则可能会用异步IO。
A B 方法是加了类锁
C D 方法是对象锁
package Test02;
import java.util.Date;
/**
* create by Sun
* 2018/6/25
*/
public class Task2 {
/**
* 类锁
*/
public synchronized static void doLongTimeTaskA(){
System.out.println("name = " + Thread.currentThread().getName() +", begain"+", time="+System.currentTimeMillis());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("name = " + Thread.currentThread().getName() + ", end"+", time="+System.currentTimeMillis());
}
/**
* static (static方法可以直接使用类调用)类锁,类锁是同步的(同步通信,及时一个线程执行,另一个线程必须等待)
*
*/
public synchronized static void doLongTimeTaskB(){
System.out.println("name = " + Thread.currentThread().getName() + ", begain"+", time="+System.currentTimeMillis());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("name = " + Thread.currentThread().getName() + ", end"+", time="+System.currentTimeMillis());
}
/**
* 对象锁(是异步的,即一个线程执行了,开启另一个线程接收,指的是不同类型的锁的实现)
* 如果两种锁都是同一种类型的,那么他们指向的顺序还是要进行堵塞,竞争,一个个的执行
* (这种只能是对象调用,对象锁)
*/
public synchronized void doLongTimeTaskC(){
System.out.println("name = " + Thread.currentThread().getName() + ", begain"+", time="+System.currentTimeMillis());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("name = " + Thread.currentThread().getName() + ", end"+", time="+System.currentTimeMillis());
}
public synchronized void doLongTimeTaskD(){
System.out.println("name = " + Thread.currentThread().getName() + ", begain"+", time="+System.currentTimeMillis());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("name = " + Thread.currentThread().getName() + ", end"+", time="+System.currentTimeMillis());
}
}
2.下面四个线程进行,测试
package Test02;
/**
* create by Sun
* 2018/6/25
*/
public class ThreadA extends Thread {
private Task2 mTask2;
public ThreadA(Task2 tk){
mTask2 = tk;
}
@Override
public void run() {
/**
* 测试不同的锁之间的变化 Test1
*/
//1. mTask2.doLongTimeTaskA();
/**
* 测试不同对象的对象锁的变化 Test2
*/
//2 mTask2.doLongTimeTaskC();
/**
* 测试类锁对不同对象的对象锁的变化 Test3
*/
mTask2.doLongTimeTaskA();
}
}
package Test02;
/**
* create by Sun
* 2018/6/26
*/
public class ThreadB extends Thread {
private Task2 mTask2;
public ThreadB(Task2 tk){
mTask2 = tk;
}
public void run() {
/**
* 测试不同的锁之间的变化
*/
//1. mTask2.doLongTimeTaskB();
/**
* 测试不同对象的对象锁的变化
*/
mTask2.doLongTimeTaskA();
}
}
package Test02;
/**
* create by Sun
* 2018/6/26
*/
public class ThreadC extends Thread {
private Task2 mTask2;
public ThreadC(Task2 tk){
mTask2 = tk;
}
public void run() {
mTask2.doLongTimeTaskC();
}
}
package Test02;
/**
* create by Sun
* 2018/6/26
*/
public class ThreadD extends Thread {
private Task2 mTask2;
public ThreadD(Task2 tk){
mTask2 = tk;
}
public void run() {
mTask2.doLongTimeTaskD();
}
}
package Test02;
/**
* create by Sun
* 2018/6/25
*/
public class main02 {
public static void main(String[] args) {
// new main02().Test1();
// new main02().Test2();
new main02().Test3();
}
public void Test1(){
Task2 task2=new Task2();
ThreadA ta=new ThreadA(task2);
ThreadB tb=new ThreadB(task2);
ThreadC tc=new ThreadC(task2);
ThreadD td=new ThreadD(task2);
ta.setName("A");
tb.setName("B");
tc.setName("C");
td.setName("D");
ta.start();
tb.start();
tc.start();
// tb.start();
td.start();
System.out.println("name = A, begain, time=1529977090289\n" +
"name = C, begain, time=1529977090289\n" +
"name = C, end, time=1529977091290\n" +
"name = D, begain, time=1529977091290\n" +
"name = A, end, time=1529977091291\n" +
"name = B, begain, time=1529977091291\n" +
"name = D, end, time=1529977092291\n" +
"name = B, end, time=1529977092292");
System.out.println("1.------总结----------对象锁和类锁是不同的锁,所以多个线程同时执行这2个不同锁的方法时,是异步的");
}
public void Test2(){
Task2 task2a=new Task2();
Task2 task2b=new Task2();
ThreadA ta=new ThreadA(task2a);
ThreadB tb=new ThreadB(task2b);
ta.setName("A");
tb.setName("B");
ta.start();
tb.start();
System.out.println("----不同对象的对于对象锁的执行的顺序-------异步执行");
System.out.println("运行结果\n"+"name = A, begain, time=1529977658292\n" +
"name = B, begain, time=1529977658292\n" +
"name = B, end, time=1529977659293\n" +
"name = A, end, time=1529977659293");
}
public void Test3(){
Task2 task2a=new Task2();
Task2 task2b=new Task2();
ThreadA ta=new ThreadA(task2a);
ThreadB tb=new ThreadB(task2b);
ta.setName("A");
tb.setName("B");
ta.start();
tb.start();
System.out.println("----类锁的对于对象锁的执行的顺序-------同步执行");
System.out.println("执行结果\n"+"name = A, begain, time=1529989536919\n" +
"name = A, end, time=1529989537920\n" +
"name = B, begain, time=1529989537920\n" +
"name = B, end, time=1529989538922");
}
}