Home  >  Article  >  Java  >  What are processes and threads?

What are processes and threads?

零下一度
零下一度Original
2017-06-25 10:18:251796browse

1 Overview

1. What is a process?

A process is a relatively independent execution unit.

2. What is a thread?

Part of the process, the actual task executor in the process, must be attached to the process. The dependence of threads on processes is mainly reflected in:

  • Threads cannot be started without the process and must be started under the premise that the process is started.

  • #Threads must sometimes get data from the process.

# 3. What is the difference between threads and processes?

Threads and processes are two relative concepts. An object is called a process relative to the execution unit it owns. From the perspective of the superior executor to which it belongs, also is called a thread.

4. The design purpose, use and significance of multi-threading

CUP can only execute one thread at any point in time. Multi-threading The essence is that multiple tasks are executed alternately at high speed. If there is no data exchange between multiple threads, can be executed independently. Using multiple threads will not reduce the total execution time.

The main purpose of multi-thread design is not to increase the execution speed, but to execute each thread relatively evenly, so that a certain thread does not hold the CPU time slice for a long time, Other threads are waiting for a long time. Because the CPU time slice switches between multiple threads quickly, beyond the range that human senses can detect, it feels like multiple tasks are being executed.

For example, when multiple people visit the same website, it takes 5 minutes for each person. If multi-threading is not used, only one person is allowed to enter the website at the same time, and most other people You have to wait for 5 minutes, the user experience is very poor. This uses multi-threading. After one person enters, the CPU turns to other users, allowing other users to enter one after another. The user experience is improved, although the total execution time is not reduced.

5.CPU scheduling mode

  • Time-sharing scheduling mode: The system allocates CPU time slices to each thread evenly .

  • Preemptive scheduling mode: Each thread competes for CPU time slices, and CPU time slices are distributed unevenly among threads.

Second thread creation

1.Java SE API provides two ways to create threads:

  • Implement the Runnable interface and pass the object of the implementation class as a parameter to the constructor of Thread.

  • # Directly inherit the Thread class.

2. No matter which method is used, the tasks that need to be performed must be placed in the run method.

3. The difference between the two creation methods:

⑴Java adopts single inheritance, that is, a class can only inherit one parent class, while allowing If a class implements multiple interfaces and creates threads by inheriting Thread, this class loses its only inheritance opportunity.

⑵ Different ways to achieve resource sharing

  • First of all, it needs to be clear that resource sharing can also be achieved by inheriting Thread to create threads. Just because multiple threads created through the new keyword are different objects, shared resources can only come from the outside, usually injected through the constructor.

  • #And by creating threads by implementing the Runnable interface, you canuse the same implementation class object to create multiple threads, realizing resource sharing , shared resources come from inside the thread.

4. Creating threads by implementing the Runnable interface not only retains the only inheritance opportunity, but also makes resource sharing operations relatively simple, so it is generally Use this method to create threads.

5. Realize resource sharing by inheriting Thread:

External classes that provide shared resources

package com.test.thread.extendsThread;public class MyClass {public int count;

}

Thread thread subclass

package com.test.thread.extendsThread;public class MyThread extends Thread {private MyClass obj;public MyThread() {super();
    }public MyThread(MyClass obj) {super();this.obj = obj;
    }

    @Overridepublic void run() {
        System.out.println("obj=" + obj);while (true) {synchronized (obj) {if (obj.count > 0) {try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + "----当前数量=" + obj.count--);
                } elsereturn;
            }
        }

    }

}

Test class

package com.test.thread.extendsThread;import org.junit.Test;import com.test.thread.synchronizedTest.demo02.MyTestRunnable;import net.sourceforge.groboutils.junit.v1.MultiThreadedTestRunner;import net.sourceforge.groboutils.junit.v1.TestRunnable;public class ThreadExtendsTest {/** * JUnit单元测试不支持多线程测试,使用GroboUtils进行多线程测试(导入架包)
     * 
     * @throws Throwable     */@Testpublic void test01() throws Throwable {
        MyClass obj = new MyClass();
        obj.count = 10;
        MyThread myth01 = new MyThread(obj);
        MyThread myth02 = new MyThread(obj);
        MyThread myth03 = new MyThread(obj);
        MyTestRunnable t01 = new MyTestRunnable(myth01);
        MyTestRunnable t02 = new MyTestRunnable(myth02);
        MyTestRunnable t03 = new MyTestRunnable(myth03);
        TestRunnable[] tr = new TestRunnable[3];
        tr[0] = t01;
        tr[1] = t02;
        tr[2] = t03;
        MultiThreadedTestRunner mttr = new MultiThreadedTestRunner(tr);
        mttr.runTestRunnables();
    }// 放在主线程中测试public static void main(String[] args) {
        MyClass obj = new MyClass();
        obj.count = 10;
        MyThread t01 = new MyThread(obj);
        MyThread t02 = new MyThread(obj);
        MyThread t03 = new MyThread(obj);
        t01.setName("t01");
        t02.setName("t02");
        t03.setName("t03");
        t01.start();
        t02.start();
        t03.start();
    }
}

 

三 线程生命周期

1.什么是线程的生命周期?

由不同阶段构成的线程从出生到死亡的整个过程,叫做线程的生命周期。

2.线程生命周期的意义

了解线程的生命周期能够更好地掌握线程的运行情况,比如线程的就绪状态,意味着不是调用start方法之后,线程立即执行。

3.生命周期的几个阶段:

  • 出生状态:线程创建完成,尚未开启前的状态。

  • 就绪状态:调用start方法开启线程,线程尚未运行的状态。

  • 运行状态:线程获取CPU时间片执行时的状态。

  • 休眠状态:线程调用sleep方法后进入指定时长的休眠状态,时间结束进入就绪状态。

  • 等待状态:监听对象在线程内部调用wait方法后,线程失去对象锁,进入等待状态。

  • 阻塞状态:线程发出输入或者输出请求后进入阻塞状态。

  • 死亡状态:run方法执行完毕,线程死亡。

四 线程的加入

一个线程A在另一个线程B内部调用join方法,B线程中止,A线程开始执行,A线程执行完毕,B线程才开始执行。

五 线程优先级

线程优先级设定了线程获取CPU时间片的概率,仅仅是一种概率,不能保证优先级高的线程一定优先获得CPU时间片。

线程优先级分为10个等级,从1-10,数值越大,优先级越高,通过setProprity(int)方法设置。

六 线程礼让

Thread.yield,线程礼让只是通知当前线程可以将资源礼让给其他线程,并不能保证当前线程一定让出资源。

七 同步机制

1.什么是线程同步机制?

使得同一资源同一时刻只能有一个线程访问的安全机制,即一个线程访问完毕,其他线程才能访问。

2.同步机制的目的

由于目标资源同一时刻只有一个线程访问,解决了线程安全问题。

3.什么是线程安全问题?

⑴线程安全问题产生条件

  • 多线程并发访问。

  • 存在可修改的共享数据。

⑵第一个线程获取了共享数据,操作结束前,第二个线程修改了该数据,导致第一个线程运算时采用的不是获取时的数据。

4.同步机制解决线程安全问题的原理

synchronized(共享对象){ 修改共享数据的代码 }

上述操作给修改共享数据的代码加了一把对象锁。任何一个对象只有一把对象锁,线程只有获得了对象锁才能访问加锁的资源。一个线程获取了对象锁,执行加锁的代码,执行完毕,归还对象锁,其他线程开始争夺对象锁,访问资源。

5.类锁

synchronized关键字加到静态方法上时,形成类锁,执行该方法上必须获取类锁。

类锁与对象锁是两种不同的锁,允许一个线程持有类锁,另一个线程持有对象锁。

6.synchronized关键字

synchronized关键字加在成员方法,该方法成为同步成员方法,由于一个对象只有一把对象锁,一个线程访问了一个同步成员方法,其他线程不能访问其他同步成员方法。

同步方法不可以被继承,同步方法在子类中失去同步机制。

7.判断条件的设置

在同步机制中,如果同步代码的执行需要满足一定条件,那么将判断条件放在锁内,保证当前获取了锁的线程在执行同步代码时满足执行条件。如果放在锁外,有可能出现当前线程获取了锁以后不满足执行条件的情况。

不存在线程安全问题的做法:

public void run() {
        System.out.println("obj=" + obj);while (true) {synchronized (obj) {if (obj.count > 0) {try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + "----当前数量=" + obj.count--);
                } elsereturn;
            }
        }

    }

If the judgment condition obj.count>0 is placed in the while statement, it may happen that when a thread enters the while statement, the count is 1, meets the condition, enters, and waits to acquire the object lock. The thread currently holding the object lock completes execution, count becomes 0, and the waiting thread acquires the object lock. When count=0, executes the synchronization block and the judgment condition fails.

8 Deadlock

1. What is a deadlock?

Thread A needs multiple locks. Thread B holds the locks that A lacks and lacks the locks held by A. Because the thread will not release the held locks before acquiring all the locks. Lock, This brings thread A and thread B into a stalemate, and the entire process is in a stagnant state.

2. How to avoid deadlock?

Reduce the number of locks in the synchronization mechanism and try to avoid the same lock appearing in multiple places.

9 Daemon thread

1. User thread?

Generally, the threads created are user threads, that is, the thread is not explicitly set as a daemon thread and is not created within the daemon thread.

2. The main thread belongs to the user thread.

3. What is a daemon thread?

A thread that runs in the background and provides services to user threads.

4. Daemon thread creation

The user thread calls the setDaemon(true) method, or creates a thread inside the daemon thread.

5. The role of the daemon thread

The daemon thread is used to provide services to user threads, such as garbage collectors.

6. The JVM terminates after all user threads have completed execution, regardless of whether the daemon thread has completed execution at this time.

7. The daemon thread runs in the background and ends automatically after all user threads end.

Comparison of ten wait and sleep methods

1. Existence range

  • The wait method is Object-level, that is, any object in java has this method, like toString.

  • #The sleep method only exists in Thread and its subclasses.

2. Function

  • ##sleep causes the current thread to sleep and releases the CPU time slice. Locks held will not be released.

  • wait is used for inter-thread communication, and the object manages all threads that use the object as a lock. Called by the lock object in the synchronization code, causing the current thread to release the object lock held by .

3. Usage method

  • The sleep method is a static method, directly through Thread Call, Thread.sleep.

  • # is used in synchronization code and is called by the lock object.

4. Related methods

  • ##obj.notify(): Randomly wake up object monitoring A thread on the server enters the ready state. Once it obtains the object lock and CPU time slice, it continues execution from the waiting point.

    It does not re-enter the run method or synchronization code.

  • obj.notifyAll(): Wake up all waiting threads on the object listener and make them all enter the ready state.

十一 ThreadLocal

1.线程局部变量,为每一个线程提供一个变量的副本,使得各个线程相对独立地操作变量,避免线程安全问题。

2.首先必须明确一点,ThreadLocal.get()获取的变量副本必须手动传入:

ThreadLocal.set(Object obj)

初次获取时,判断线程局部变量中是否保存有变量副本,如果没有则手动传入,在该线程中下次获取的就是初次传入的对象。

3.ThreadLocal的目的是保证在一个线程内部,一次创建,多次获取。

4.基本原理:
      将初次传入的变量与线程绑定,线程不变,变量不变。

十二 GroboUtils多线程测试

   1.JUnit测试不支持多线程,GroboUtils提供了对多线程测试的支持,使用时需要导入架包。

    2.几个比较重要的类:

  • TestRunnable:实现了Runnable接口,run方法中运行的是runTest方法,runTest方法是一个抽象方法。

  • MultiThreadedTestRunner:负责管理并开启多个线程。

    3.测试步骤

⑴继承TestRunnable,实现其中的抽象方法runTest,将需要运行的代码放入该方法中。通常为子类定义一个有参构造方法,方法形参为需要测试的线程,在runTest方法中调用测试线程的run方法,从而将将需要执行的代码注入runTest方法中。

⑵创建测试线程数组,将需要测试的TestRunnable实现类传入其中:

TestRunnable[] tr=new TestRunnable[len];

⑶根据测试线程数组创建线程管理与运行对象并开启多线程:

MultiThreadedTestRunner mttr=new MultiThreadedTestRunner(tr);
mttr.runTestRunnables();

The above is the detailed content of What are processes and threads?. For more information, please follow other related articles on the PHP Chinese website!

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