Java locks are divided into two types:
-
Object lock (also known instance lock
synchronized
): This is a lock for that instance of the object (the current object).synchronized
Class is the current instance (the current object) for locking, to prevent other threads access class for all synchronized block of this example , note that there is "current instance of the class", two different instances of the class is no such constraint a.
Each object has a lock, and is unique . -
Locks (also known as global lock
static synchronized
): This is a lock for the class, regardless instance a number of objects , the thread is still sharing the lock.static synchronized
Limiting all instances of the class multiple threads simultaneously access the class code block corresponds . (实例.fun
Actually equivalentclass.fun
)
The following tests carried out several conditions: it is used to test a range of locks
1, two static methods are locked
package test2;
public class Test2 {
public synchronized void add(){
System.out.println("1 :) ");
t();
}
public void add1(){
System.out.println("2 :( ");
t();
}
public void t(){
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
2, two methods are non-static lock
package test2;
public class Test1 extends Thread{
private int flag;
private Test2 t;
public Test1(int f , Test2 t2){
flag = f;
t = t2;
}
public void run(){
if(flag == 1)
try {
// Test2.add();
t.add();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(flag == 2)
try {
t.add1();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) throws InterruptedException {
Test2 t = new Test2();
Test1 t1 = new Test1(1,t);
Test1 t2 = new Test1(2,t);
t1.start();
t2.start();
}
}
class Test2 {
public synchronized void add(){
System.out.println("1 :) "+System.currentTimeMillis());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public synchronized void add1(){
System.out.println("2 :( "+System.currentTimeMillis());
}
}
Result: another lock will lock the object
3, non-static methods, static methods are locked
package test2;
public class Test1 extends Thread{
private int flag;
private Test2 t;
public Test1(int f , Test2 t2){
flag = f;
t = t2;
}
public void run(){
if(flag == 1)
try {
Test2.add();
// t.add();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(flag == 2)
try {
t.add1();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) throws InterruptedException {
Test2 t = new Test2();
Test1 t1 = new Test1(1,t);
Test1 t2 = new Test1(2,t);
t1.start();
t2.start();
}
}
class Test2 {
public synchronized static void add(){
System.out.println("1 :) "+System.currentTimeMillis());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public synchronized void add1(){
System.out.println("2 :( "+System.currentTimeMillis());
}
}
Results: Static objects can not lock locked not locked non-static method
4, static method lock, non-static method does not lock
package test2;
public class Test1 extends Thread{
private int flag;
private Test2 t;
public Test1(int f , Test2 t2){
flag = f;
t = t2;
}
public void run(){
if(flag == 1)
try {
Test2.add();
// t.add();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(flag == 2)
try {
t.add1();
// Test2.add1();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) throws InterruptedException {
Test2 t = new Test2();
Test1 t1 = new Test1(1,t);
Test1 t2 = new Test1(2,t);
t1.start();
t2.start();
}
}
class Test2 {
public synchronized static void add(){
System.out.println("1 :) "+System.currentTimeMillis());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void add1(){
System.out.println("2 :( "+System.currentTimeMillis());
}
}
Results: The static method lock, non-static method can not lock
5, non-static method lock, unlocked the static method
package test2;
public class Test1 extends Thread{
private int flag;
private Test2 t;
public Test1(int f , Test2 t2){
flag = f;
t = t2;
}
public void run(){
if(flag == 1)
try {
Test2.add();
// t.add();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(flag == 2)
try {
t.add1();
// Test2.add1();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) throws InterruptedException {
Test2 t = new Test2();
Test1 t1 = new Test1(1,t);
Test1 t2 = new Test1(2,t);
t1.start();
t2.start();
}
}
class Test2 {
public static void add(){
System.out.println("1 :) "+System.currentTimeMillis());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public synchronized void add1(){
System.out.println("2 :( "+System.currentTimeMillis());
}
}
Result: still not lock! ! !
6, two static methods, a lock is not a lock
package test2;
public class Test1 extends Thread{
private int flag;
private Test2 t;
public Test1(int f , Test2 t2){
flag = f;
t = t2;
}
public void run(){
if(flag == 1)
try {
Test2.add();
// t.add();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(flag == 2)
try {
// t.add1();
Test2.add1();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) throws InterruptedException {
Test2 t = new Test2();
Test1 t1 = new Test1(1,t);
Test1 t2 = new Test1(2,t);
t1.start();
t2.start();
}
}
class Test2 {
public synchronized static void add(){
System.out.println("1 :) "+System.currentTimeMillis());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void add1(){
System.out.println("2 :( "+System.currentTimeMillis());
}
}
Results: The static method lock, not lock unlocked the static method
7, two non-static method, a lock is not a lock
package test2;
public class Test1 extends Thread{
private int flag;
private Test2 t;
public Test1(int f , Test2 t2){
flag = f;
t = t2;
}
public void run(){
if(flag == 1)
try {
// Test2.add();
t.add();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(flag == 2)
try {
t.add1();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) throws InterruptedException {
Test2 t = new Test2();
Test1 t1 = new Test1(1,t);
Test1 t2 = new Test1(2,t);
t1.start();
t2.start();
}
}
class Test2 {
private int i = 0;
public synchronized void add(){
System.out.println("1 :) "+System.currentTimeMillis());
}
public void add1(){
System.out.println("2 :( "+System.currentTimeMillis());
}
}
The results: you can see, non-static method after the lock, static method does not lock unlocked
8, two non-static method, a lock, a lock not, call the same method
package test2;
public class Test1 extends Thread{
private int flag;
private Test2 t;
public Test1(int f , Test2 t2){
flag = f;
t = t2;
}
public void run(){
if(flag == 1)
try {
// Test2.add();
t.add();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(flag == 2)
try {
t.add1();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
Test2 t = new Test2();
Test1 t1 = new Test1(1,t);
Test1 t2 = new Test1(2,t);
t1.start();
t2.start();
}
}
class Test2 {
public synchronized void add(){
System.out.println("1 :) "+System.currentTimeMillis());
t();
}
public void add1(){
System.out.println("2 :( "+System.currentTimeMillis());
t();
}
public void t(){
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Result: not lock the t () method add in the way in
9, two non-static method, a lock, a locking is not, call the same method for operating the same variable
package test2;
public class Test1 extends Thread{
private int flag;
private Test2 t;
public Test1(int f , Test2 t2){
flag = f;
t = t2;
}
public void run(){
if(flag == 1)
try {
// Test2.add();
t.add();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(flag == 2)
try {
t.add1();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) throws InterruptedException {
Test2 t = new Test2();
for(int i = 0 ; i < 1000 ; i++){
Test1 t1 = new Test1(1,t);
Test1 t2 = new Test1(2,t);
t1.start();
t2.start();
}
Thread.sleep(30);
System.out.println(t.getI());
}
}
class Test2 {
private int i = 0;
public synchronized void add(){
// System.out.println("1 :) "+System.currentTimeMillis());
t();
}
public void add1(){
// System.out.println("2 :( "+System.currentTimeMillis());
t();
}
public void t(){
try {
i++;
// Thread.sleep(5000);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public int getI() {
return i;
}
public void setI(int i) {
this.i = i;
}
}
Result: a locking method does not guarantee the security of the operating variables of the method was invoked
总结:不管是什么锁,都只能锁住相同类型(静态-静态,非静态-非静态)的带锁的对象。