Synchronize
To perform a task, we need to rely on the completion of another task.
Standard program execution flow is synchronized only on a function execution is completed, the next function before they can begin, this is the dependency
asynchronous
To perform a task, do not rely on the completion of another task.
The concept of concurrency, just need to tell the need to do another task, it will go directly to the Executive
Object lock: Only when competing for the same target
- synchronized modification
非静态方法
,代码块synchronized (this)
,synchronized (非this对象)
thread synchronization code to be executed corresponding need to acquire the object lock
Lock method
An example of the first show did not lock, according to his output code can know, because we instantiate an object, and then open a thread to pass a parameter a
in the past, to perform System.out.println("a arrived");
he began to sleep 2s, this at the same time open another thread, the same call to the same method of the same object, passed b
in the past, so there are the following results
public class main {
public static void main(String[] args) throws IOException {
person p = new person();
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
p.addstr("a");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
p.addstr("b");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
}
}
class person{
private int number = 0;
public void addstr(String string) throws InterruptedException {
if (string.equals("a")) {
number = 100;
System.out.println("a arrived");
Thread.sleep(2000);
}else {
number = 200;
System.out.println("b arrived");
}
System.out.println(string + " number=" + String.valueOf(number));
}
}
Output:
a arrived
b arrived
b number=200
a number=200
Minor changes to the addstr
method plus lock, this time competing multi-threaded locking method of the same object, it is necessary in order to have to wait on a call to release the lock
class person{
private int number = 0;
synchronized public void addstr(String string) throws InterruptedException {
if (string.equals("a")) {
number = 100;
System.out.println("a arrived");
Thread.sleep(2000);
}else {
number = 200;
System.out.println("b arrived");
}
System.out.println(string + " number=" + String.valueOf(number));
}
}
Another case is, a method of locking two classes, two different threads at the same time calls the object locked, this case, after the test, the output display, a second method for performing locked need to wait, that is 一个类内,使用一个锁,锁住一个或多个方法
.
person p = new person();
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
p.printA(string);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
p.printB(string);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
}
}
class person{
private int number = 0;
synchronized public void printA(String string) throws InterruptedException {
System.out.println("A 进入线程!");
Thread.sleep(2000);
System.out.println("A 离开线程!");
}
synchronized public void printB(String string) throws InterruptedException {
System.out.println("B 进入线程!");
System.out.println("B 离开线程!");
}
}
Output:
A 进入线程!
A 离开线程!
B 进入线程!
B 离开线程!
synchronized (this)
The above class person again slight modification, we lock a block of code, multiple threads when the same 竞争同一个对象
is 这个代码块
needed to lock in accordance with the rules, a release, before the next use, the output supra
class person{
private int number = 0;
public void addstr(String string) throws InterruptedException {
synchronized(this) {
if (string.equals("a")) {
number = 100;
System.out.println("a arrived");
Thread.sleep(2000);
}else {
number = 200;
System.out.println("b arrived");
}
System.out.println(string + " number=" + String.valueOf(number));
}
}
}
It should be noted it because multithreading competition rules only the contents of this block of code is the use of locks, which is the code block above, the following are not synchronized, modify the code, the synchronization code block above this, plus the following two outputs System.out.println(string + "来了");、System.out.println(string + " number=" + String.valueOf(number));
, this time the output of the following two results. A first explained b来了
output, because System.out.println(string + "来了");
this one did not lock, so the first parameter with a a
time of sleep, the second thread running to finish the output here b来了
, it is here to stay, ranking a thread releases the lock, it can continue. As result, there are two, it is because another output statement System.out.println(string + " number=" + String.valueOf(number));
unlocked, fully depending on who fast, who performs, or concurrent execution are possible
class person{
private int number = 0;
public void addstr(String string) throws InterruptedException {
System.out.println(string + "来了");
synchronized(this) {
if (string.equals("a")) {
number = 100;
System.out.println("a arrived");
Thread.sleep(2000);
}else {
number = 200;
System.out.println("b arrived");
}
}
System.out.println(string + " number=" + String.valueOf(number));
}
}
Output:
a来了
a arrived
b来了
b arrived
a number=100
b number=200
or
a来了
a arrived
b来了
b arrived
b number=200
a number=200
Same, synchronized (this) also exist in the same class, or using a lock with a plurality of code blocks, the code block is not the vertical sync
class person{
public String son;
public person(String son) {
this.son = son;
}
private int number = 0;
synchronized public void printA(String string) throws InterruptedException {
System.out.println("A 进入线程!");
Thread.sleep(2000);
System.out.println("A 离开线程!");
}
public void printB(String string) throws InterruptedException {
System.out.println("B ready!");
synchronized (this) {
System.out.println("B 进入线程!");
System.out.println("B 离开线程!");
}
}
Output:
A 进入线程!
B ready!
A 离开线程!
B 进入线程!
B 离开线程!
synchronized (this non-target)
As long as an object with multiple threads access the object is locked, and the same, we need to lock in accordance with the rules, as the following example, although the examples of two different objects, but they are the same access a String object, there is competition. In fact, can be labeled as a locked object, any use of this thread is locked object, the equivalent of being marked, labeled thread execution place to synchronized statement, it is necessary to order, there is no concurrent get on
public static void main(String[] args) throws IOException {
String string = "son";
person p = new person(string);
person p1 = new person(string);
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
p.addstr("a");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
p1.addstr("b");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
}
}
class person{
public String son;
public person(String son) {
this.son = son;
}
private int number = 0;
public void addstr(String string) throws InterruptedException {
System.out.println(string + "来了");
synchronized(son) {
if (string.equals("a")) {
number = 100;
System.out.println("a arrived");
Thread.sleep(2000);
}else {
number = 200;
System.out.println("b arrived");
}
}
System.out.println(string + " number=" + String.valueOf(number));
}
}
Locks
- synchronized modification
静态方法
,synchronized(类.class)
the lock is the corresponding class, we need to obtain类锁
class lock is actually using the object lock, when loading a class file, create an instance of java.lang.Class class, a class when the lock is locked java. examples of class lang.Class
The following example is 对象锁
different use person对象
, i.e. the use of different lock with the person object
String string = "son";
person p = new person(string);
person p1 = new person(string);
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
p.printA(string);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
p1.printB(string);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
}
}
class person{
public String son;
public person(String son) {
this.son = son;
}
private int number = 0;
synchronized public void printA(String string) throws InterruptedException {
System.out.println("A 进入线程!");
Thread.sleep(2000);
System.out.println("A 离开线程!");
}
synchronized public void printB(String string) throws InterruptedException {
System.out.println("B ready!");
System.out.println("B 进入线程!");
System.out.println("B 离开线程!");
}
}
对象锁
Output:
A 进入线程!
B ready!
B 进入线程!
B 离开线程!
A 离开线程!
Plus minor modifications static
, let us use 类锁
, even though instances of different objects, but the use of the same class, the output at this time is not the same, there is also used同一个类,使用一个锁锁住一个或多个方法、代码块
class person{
public String son;
public person(String son) {
this.son = son;
}
private int number = 0;
synchronized public static void printA(String string) throws InterruptedException {
System.out.println("A 进入线程!");
Thread.sleep(2000);
System.out.println("A 离开线程!");
}
synchronized public static void printB(String string) throws InterruptedException {
System.out.println("B ready!");
System.out.println("B 进入线程!");
System.out.println("B 离开线程!");
}
}
Output:
A 进入线程!
A 离开线程!
B ready!
B 进入线程!
B 离开线程!
Again introducing a small experience point: 类锁
and 对象锁
mix
the same method using the above code is slightly modified, can be seen from the output, the lock of the object blocks of code, even for the same object, there is no mechanism to lock performed, illustrating类锁和对象锁混用的情况下,只有类锁有效,对象锁无效
this: the object represented by the current instance of the class
person p = new person(string);
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
p.printA(string);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
p.printB(string);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
}
}
class person{
public String son;
public person(String son) {
this.son = son;
}
private int number = 0;
synchronized public static void printA(String string) throws InterruptedException {
System.out.println("A 进入线程!");
Thread.sleep(2000);
System.out.println("A 离开线程!");
}
public void printB(String string) throws InterruptedException {
System.out.println("B ready!");
synchronized (this) {
System.out.println("B 进入线程!");
System.out.println("B 离开线程!");
}
}
}
In order to prove that the order does not matter and locks, reverse the order to prove
class person{
public String son;
public person(String son) {
this.son = son;
}
private int number = 0;
public void printA(String string) throws InterruptedException {
System.out.println("A ready!");
synchronized (this) {
System.out.println("A 进入线程!");
Thread.sleep(2000);
System.out.println("A 离开线程!");
}
}
synchronized public static void printB(String string) throws InterruptedException {
System.out.println("B 进入线程!");
System.out.println("B 离开线程!");
}
}
Output:
A ready!
A 进入线程!
B 进入线程!
B 离开线程!
A 离开线程!
Java class object lock and lock comprehensive analysis (multi-threaded synchronized keyword)