The basic use of multithreading
There are two ways to create threads
-
Thread class inheritance
public class MyThread extends Thread{ @Override public void run(a) { System.out.println(getName()+"--->run"); } public static void main(String[] args) throws InterruptedException { Thread a = new MyThread(); Thread b = newMyThread(); a.start(); b.start(); a.join(); b.join(); }}Copy the code
-
Implement the Runnable interface
public static void main(String[] args) { Runnable runnable = new Runnable() { @Override public void run(a) { System.out.println("i'm runnable"); }};new Thread(runnable).start(); } Copy the code
Abbreviations:
public static void main(String[] args) { new Thread(()->{ System.out.println("i'm simple"); }).start(); } Copy the code
Thread synchronization
If synchronization is not set
class MyRunnableImpl implements Runnable{
private int x = 0;
@Override
public void run(a) {
for(int i =0; i<10000; i++){ x = x+1;
x = x-1; }}public int getX(a) {
returnx; }}public class SyncTest {
public static void main(String[] args) throws InterruptedException {
MyRunnableImpl runnable = new MyRunnableImpl();
Thread thread = new Thread(runnable);
Thread thread2 = newThread(runnable); thread.start(); thread2.start(); thread.join(); thread2.join(); System.out.println(runnable.getX()); }}Copy the code
The running result of this program: 28
But according to the program’s logic, it should be 0, and the reason it’s not 0 is because there’s no synchronization
Set synchronization using the synchronized keyword
class MyRunnableImpl implements Runnable{
private int x = 0;
@Override
public void run(a) {
for(int i =0; i<10000; i++){synchronized (this){
x = x+1;
x = x-1; }}}public int getX(a) {
returnx; }}public class SyncTest {
public static void main(String[] args) throws InterruptedException {
MyRunnableImpl runnable = new MyRunnableImpl();
Thread thread = new Thread(runnable);
Thread thread2 = newThread(runnable); thread.start(); thread2.start(); thread.join(); thread2.join(); System.out.println(runnable.getX()); }}Copy the code
The run result is 0
The synchronized keyword can also be added to a function to indicate that the contents of the function body are locked
class MyRunnableImpl implements Runnable{
private int x = 0;
@Override
public synchronized void run(a) {
for(int i =0; i<10000; i++){ x = x+1;
x = x-1; }}public int getX(a) {
returnx; }}public class SyncTest {
public static void main(String[] args) throws InterruptedException {
MyRunnableImpl runnable = new MyRunnableImpl();
Thread thread = new Thread(runnable);
Thread thread2 = newThread(runnable); thread.start(); thread2.start(); thread.join(); thread2.join(); System.out.println(runnable.getX()); }}Copy the code
Synchronized operations are not required
The JVM specification defines several atomic operations:
- Basic type (
long
anddouble
Except for), for example:int n = m
; - Reference type assignment, for example:
List<String> list = anotherList
.
Long and double are 64-bit data. The JVM does not specify whether 64-bit assignment is an atomic operation, but x64 JVMS implement long and double assignments as atomic operations.
Statements that operate on a single atom do not need to be synchronized
Java multithreading – Threads communicate wait and Notify