Basic use of synchronized
For threads, if multiple threads are only executed separately from each other, it does not make much sense in itself. Generally speaking, multiple threads are required to cooperate with each other to perform work. Such use will affect the system. Bring practical meaning.
In Java, multiple threads are supported to access an object or member variables in an object at the same time, but if there is no protection mechanism, data inconsistency will occur. The effect is as follows:
public class TestThread {
public static void main(String[] args) {
TestThread testThread = new TestThread();
new Thread(new Runnable() {
@Override
public void run() {
testThread.print();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
testThread.print();
}
}).start();
}
public void print(){
for(int i=0;i<1000;i++){
System.out.println(Thread.currentThread().getName()+"--->"+i);
}
}
}
If you want to solve this problem now, you can use a lock to solve it. Synchronized can modify the method or use it in the form of synchronization block. It mainly ensures that multiple threads can only be in the method or synchronization block at the same time. It ensures the visibility and exclusivity of thread access to variables. Also known as the built-in lock mechanism.
Object lock
If a thread that owns the same object lock in a synchronized code block (or synchronization method), if one thread acquires the lock, other threads can only acquire the lock after the thread releases the lock.
this lock object
public class TestThread {
public static void main(String[] args) {
TestThread testThread = new TestThread();
new Thread(new Runnable() {
@Override
public void run() {
testThread.print();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
testThread.print();
}
}).start();
}
//同步代码块
public void print(){
synchronized (this){
for(int i=0;i<1000;i++){
System.out.println(Thread.currentThread().getName()+"--->"+i);
}
}
}
//同步方法,synchronized 默认this作为锁对象
/* public synchronized void print(){
for(int i=0;i<1000;i++){
System.out.println(Thread.currentThread().getName()+"--->"+i);
}
}*/
}
Constant lock object
public class TestThread {
public static void main(String[] args) {
TestThread testThread = new TestThread();
new Thread(new Runnable() {
@Override
public void run() {
testThread.print();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
testThread.print();
}
}).start();
//调用静态方法
new Thread(new Runnable() {
@Override
public void run() {
TestThread.print2();
}
}).start();
}
private static final Object obj = new Object();
public void print(){
synchronized (obj){
for(int i=0;i<1000;i++){
System.out.println(Thread.currentThread().getName()+"--->"+i);
}
}
}
public static void print2(){
synchronized (obj){
for(int i=0;i<1000;i++){
System.out.println(Thread.currentThread().getName()+"--->"+i);
}
}
}
}
Class lock
Synchronize the runtime class as a lock when modifying a static method
public class TestThread {
public static void main(String[] args) {
TestThread testThread = new TestThread();
new Thread(new Runnable() {
@Override
public void run() {
testThread.print();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
testThread.print2();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
TestThread.print2();
}
}).start();
}
//将TestThread的字节码文件作为锁对象
public synchronized void print(){
synchronized (TestThread.class){
for(int i=0;i<1000;i++){
System.out.println(Thread.currentThread().getName()+"--->"+i);
}
}
}
//synchronized修饰静态方法
public static synchronized void print2(){
for(int i=0;i<1000;i++){
System.out.println(Thread.currentThread().getName()+"--->"+i);
}
}
}
The above three methods all use the bytecode file of TestThread as the lock object, so synchronization can also be achieved
Lock reentrancy
If the current thread already owns the lock object, the same lock object can be acquired again and again without deadlock.
public class Reentrant {
public synchronized void function1(){
System.out.println("同步方法1");
function2();
}
public synchronized void function2(){
System.out.println("同步方法2");
function3();
}
public synchronized void function3(){
System.out.println("同步方法3");
}
public static void main(String[] args) {
Reentrant reentrant = new Reentrant();
new Thread(new Runnable() {
@Override
public void run() {
reentrant.function1();
}
}).start();
}
}