Home >类库下载 >java类库 >Basic use of Java multithreading

Basic use of Java multithreading

高洛峰
高洛峰Original
2016-11-14 09:32:471816browse

1. Concept

1. Process

1.1 Process: It is an ongoing program. Each process execution has an execution sequence, which is an execution path, or a control unit.

1.2 Thread: It is an independent control unit in the process. The thread controls the execution of the process. There is at least one thread in a process.

1.3 Example of java VM:

When Java VM starts, there will be a process java.exe. There is at least one thread in this process that is responsible for running the java program, and the code run by this thread exists in the main method. This thread Call it the main thread. Extension: Actually, jvm is explained in more detail. JVM starts more than one thread, as well as the thread responsible for the garbage collection mechanism. 2. The significance of multi-threading: improving execution efficiency. 2. Creation of multi-threads. 1. Multi-thread creation The first way is to inherit the Thread class

1.1 Define the class to inherit Thread, and override the run method in the Thread class to store the customized code in the run method and let the thread run

1.2 Call the thread's start method. The method has two functions: start the thread and call the run method

1.3 When running with multiple threads, the running results are different every time, because multiple threads obtain the execution rights of the CPU, and whoever the CPU executes will run. To be clear , only one program can be running at a certain time. (Except for multi-core), the CPU is rapidly switching to achieve the effect of seemingly running at the same time. We can visualize the running behavior of multi-threads competing for the execution power of the CPU. This is a characteristic of multithreading, randomness. Whoever grabs it will execute it. As for how long it will take, the CPU has the final say.

public class Demo extends Thread{ 
    public void run(){ 
        for (int x = 0; x < 60; x++) { 
            System.out.println(this.getName()+"demo run---"+x); 
        } 
    } 
     
    public static void main(String[] args) { 
        Demo d=new Demo();//创建一个线程 
        d.start();//开启线程,并执行该线程的run方法 
        d.run(); //仅仅是对象调用方法,而线程创建了但并没有运行 
        for (int x = 0; x < 60; x++) { 
            System.out.println("Hello World---"+x); 
        } 
    } 
 
}

2 The second way to create multi-threads, steps:

2.1 Define a class to implement the Runnable interface

2.2 Override the run method in the Runnable interface: store the code to be run by the thread in the run method

2.3. Pass The Thread class creates a thread object

2.4. Pass the subclass object of the Runnable interface as an actual parameter to the constructor of the Thread class

Why should we pass the subclass object of the Runnable interface to the constructor of Thread: because of the custom run method The object it belongs to is a subclass object of the Runnable interface, so if you want the thread to execute the run method of the specified object, you must clarify the object to which the run method belongs

2.5. Call the start method of the Thread class to start the thread and call the Runnable interface subclass method

/* 
 * 需求:简易买票程序,多个窗口同时卖票 
 */ 
public class Ticket implements Runnable { 
    private static int tick = 100; 
    Object obj = new Object(); 
    boolean flag=true; 
 
    public void run() { 
        if(flag){ 
            while (true) { 
                synchronized (Ticket.class) { 
                    if (tick > 0) { 
                        System.out.println(Thread.currentThread().getName() 
                                + "code:" + tick--); 
                    } 
                } 
            } 
        }else{ 
            while(true){ 
                show(); 
            } 
        } 
         
    } 
 
    public static synchronized void show() { 
        if (tick > 0) { 
            System.out.println(Thread.currentThread().getName() + "show:" 
                    + tick--); 
        } 
    } 
 
} 
 
class ThisLockDemo { 
    public static void main(String[] args) { 
        Ticket t = new Ticket(); 
 
        Thread t1 = new Thread(t); 
        try { 
            Thread.sleep(10); 
        } catch (Exception e) { 
            // TODO: handle exception 
        } 
        t.flag=false; 
        Thread t2 = new Thread(t); 
        //Thread t3 = new Thread(t); 
        //Thread t4 = new Thread(t); 
 
        t1.start(); 
        t2.start(); 
        //t3.start(); 
        //t4.start(); 
    } 
}

3. What is the difference between implementation and inheritance?

3.1. The implementation avoids the limitations of single inheritance. It is recommended to use the implementation when defining threads

3.2. Inherit the Thread class: the thread code is stored in Thread In the subclass run method

3.3. Implement Runnable: Thread code is stored in the subclass run method of the interface

4. Multi-threading - characteristics of run and start

4.1 Why should we overwrite the run method:

Thread class uses For describing threads, this class defines a function for storing the code to be run by the thread. The storage function is the run method, which means that the run method in the Thread class is used to store the code to be run by the thread

5. Multi-thread running status

Create thread-run---sleep()/wait()--freeze---notify()---wake up

Create thread-run---stop()-die

create Thread-run---did not grab the cpu execution right--temporarily frozen

6. Get the thread object and its name

6.1. Threads have their own default names, and the number starts from 0

6.2.static Thread currentThread() :Get the current thread object

6.3.getName(): Get the thread name

6.4. Set the thread name: setName() or use the constructor

public class Test extends Thread{ 
     
    Test(String name){ 
        super(name); 
    } 
     
    public void run(){ 
        for (int x = 0; x < 60; x++) { 
            System.out.println((Thread.currentThread()==this)+"..."+this.getName()+" run..."+x); 
        } 
    } 
} 
 
class ThreadTest{ 
    public static void main(String[] args) { 
        Test t1=new Test("one---"); 
        Test t2=new Test("two+++"); 
        t1.start(); 
        t2.start(); 
        t1.run(); 
        t2.run(); 
        for (int x = 0; x < 60; x++) { 
            System.out.println("main----"+x); 
        } 
    } 
}

3. Multi-threading security issues

1. Multi-threading security issues Reasons:

1.1. When multiple statements are operating on the same thread to share data, one thread has only executed part of the multiple statements, and before the execution is completed, another thread participates in the execution, resulting in shared data errors

1.2. Solution: For statements that share data for multiple operations, only one thread can be executed. During the execution process, other threads cannot participate in the execution. 1.3. Java provides a professional solution to multi-threaded security issues. The method is to synchronize the code block:

Synchronized (object) {code that needs to be synchronized}. The object is like a lock. The thread holding the lock can execute in synchronization. The thread that does not hold the lock can execute the CPU even if it obtains the CPU execution right. No, because the lock is not acquired

2. Prerequisites for synchronization:

2.1. There must be 2 or more threads

2.2. Multiple threads must use the same lock

2.3. The advantage is that it is solved Multi-threading security issues

2.4. The disadvantage is that multiple threads need to determine the lock, which consumes more resources

2.5. Synchronization function

Define the synchronization function and modify it with synchronized in the method

/* 
 * 需求: 
 * 银行有一个金库,有两个储户分别存300元,每次存100元,存3次 
 * 目的:该程序是否有安全问题,如果有,如何解决 
 * 如何找问题: 
 * 1.明确哪些代码是多线程代码 
 * 2.明确共享数据 
 * 3.明确多线程代码中哪些语句是操作共享数据的 
 */ 
 
public class Bank { 
 
    private int sum; 
 
    Object obj = new Object(); 
 
    //定义同步函数,在方法钱用synchronized修饰即可 
    public synchronized void add(int n) { 
        //synchronized (obj) { 
            sumsum = sum + n; 
            try { 
                Thread.sleep(10); 
            } catch (InterruptedException e) { 
                // TODO Auto-generated catch block 
                e.printStackTrace(); 
            } 
            System.out.println("sum=" + sum); 
        //} 
 
    } 
 
} 
 
class Cus implements Runnable { 
    private Bank b = new Bank(); 
 
    public void run() { 
        for (int x = 0; x < 3; x++) { 
            b.add(100); 
        } 
    } 
} 
 
class BankDemo { 
    public static void main(String[] args) { 
        Cus c = new Cus(); 
        Thread t1 = new Thread(c); 
        Thread t2 = new Thread(c); 
 
        t1.start(); 
        t2.start(); 
    } 
}

6. Synchronous lock

6.1 The function needs to be called by the object, then the function has an owning object reference, which is this., so the lock used by the synchronization function is this

6.2. The lock of the static function is the class object

When entering the memory statically, there is no Objects of this class, but there must be a bytecode file object corresponding to this class, class name.class, the type of the object is Class

6.3. Static synchronization method, the lock used is the bytecode file of the class where the method is located Object, class name.class

/* 
 * 需求:简��买票程序,多个窗口同时卖票 
 */ 
public class Ticket implements Runnable { 
    private static int tick = 100; 
    Object obj = new Object(); 
    boolean flag=true; 
 
    public void run() { 
        if(flag){ 
            while (true) { 
                synchronized (Ticket.class) { 
                    if (tick > 0) { 
                        System.out.println(Thread.currentThread().getName() 
                                + "code:" + tick--); 
                    } 
                } 
            } 
        }else{ 
            while(true){ 
                show(); 
            } 
        } 
         
    } 
 
    public static synchronized void show() { 
        if (tick > 0) { 
            System.out.println(Thread.currentThread().getName() + "show:" 
                    + tick--); 
        } 
    } 
 
} 
 
class ThisLockDemo { 
    public static void main(String[] args) { 
        Ticket t = new Ticket(); 
 
        Thread t1 = new Thread(t); 
        try { 
            Thread.sleep(10); 
        } catch (Exception e) { 
            // TODO: handle exception 
        } 
        t.flag=false; 
        Thread t2 = new Thread(t); 
        //Thread t3 = new Thread(t); 
        //Thread t4 = new Thread(t); 
 
        t1.start(); 
        t2.start(); 
        //t3.start(); 
        //t4.start(); 
    } 
}

7. Multi-threading, singleton mode-lazy style

懒汉式与饿汉式的区别:懒汉式能延迟实例的加载,如果多线程访问时,懒汉式会出现安全问题,可以使用同步来解决,用同步函数和同步代码都可以,但是比较低效,用双重判断的形式能解决低效的问题,加同步的时候使用的锁是该类锁属的字节码文件对象

/* 
 * 单例模式 
 */ 
//饿汉式 
public class Single { 
    private static final Single s=new Single(); 
    private Single(){} 
    public static Single getInstance(){ 
        return s; 
    } 
 
} 
 
//懒汉式 
class Single2{ 
    private static Single2 s2=null; 
    private Single2(){} 
    public static Single2 getInstance(){ 
        if(s2==null){ 
            synchronized(Single2.class){ 
                if(s2==null){ 
                    s2=new Single2();     
                } 
            } 
        } 
        return s2; 
    } 
} 
 
class SingleDemo{ 
    public static void main(String[] args) { 
        System.out.println("Hello World"); 
    } 
}

8.多线程-死锁

同步中嵌套同步会出现死锁

/* 
 * 需求:简易买票程序,多个窗口同时卖票 
 */ 
public class DeadTest implements Runnable { 
    private boolean flag; 
 
    DeadTest(boolean flag) { 
        this.flag = flag; 
    } 
 
    public void run() { 
        if (flag) { 
            synchronized(MyLock.locka){ 
                System.out.println("if locka"); 
                synchronized(MyLock.lockb){ 
                    System.out.println("if lockb"); 
                } 
            } 
        } else { 
            synchronized(MyLock.lockb){ 
                System.out.println("else lockb"); 
                synchronized(MyLock.locka){ 
                    System.out.println("else locka"); 
                } 
            } 
        } 
    } 
} 
 
class MyLock{ 
    static Object locka=new Object(); 
    static Object lockb=new Object(); 
} 
 
class DeadLockDemo { 
    public static void main(String[] args) { 
        Thread t1 = new Thread(new DeadTest(true)); 
        Thread t2 = new Thread(new DeadTest(false)); 
 
        t1.start(); 
        t2.start(); 
    } 
}


Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn