多线程

2018-01-20  本文已影响0人  鉴闻俗说

一、线程的概念

1、什么是线程

线程就是程序中单独顺序的控制流。线程本身不能运行,它只能用于程序中。

2、什么是多线程

多线程是指在单个程序中可以同时运行多个不同的线程执行不同的任务。

3、什么是进程

进程就是运行中的程序。一个进程可以运行着多个线程。

4、线程使用的资源和环境

线程是程序内的顺序控制流,只能使用分配给程序的资源和环境。

5、多线程编程的目的

最大限度地利用CPU资源。当某一个线程的处理不需要占用CPU而只和I/O等资源打交道时,让需要占用CPU资源的其它线程有机会获得CPU资源。

6、单线程

Java中如果我们没有产生自己的线程,那么系统就会给我们产生一个线程(主线程,main方法就在主线程上运行),我们的程序都是由线程来执行的。

7、多线程

8、多任务处理的两种方式

9、线程与进程的区别

(1)多个进程的内部数据和状态都是完全独立的,而多线程是共享一块内存空间和一组系统资源,有可能互相影响。
(2)线程本身的数据通常只有寄存器数据,以及一个程序执行时使用的栈,所以线程切换比进程切换的负担小。
(3)多线程程序比多进程程序需要更少的管理费用。进程需要独立的地址空间,进程间通信昂贵、受限,进程间的转换昂贵。线程共享地址空间、同一个进程,线程间通信便宜、转换成本低。
(4)多线程可以帮助你编写出CPU最大利用率的高效程序,使得空闲时间保持最低。

二、线程的实现

在Java中通过run方法为线程指明要完成的任务。有两种技术来为线程提供run方法。

1、继承Thread类并重载run方法

class Thread1 extends Thread
{   
    @Override
    public void run()
    {
        ...
    }
}
Thread1 t1 = new Thread1();
t1.start();
/**
 * 通过继承Thread类并重写run方法实现线程
 * 本例中创建了两个不同的线程
 *
 */
public class ThreadTest
{
    public static void main(String[] args)
    {
        Thread1 t1 = new Thread1("thread first");
        Thread2 t2 = new Thread2("thread second");
        
        System.out.println(t1.getName());
        System.out.println(t2.getName());
        
        //start方法是启动线程的唯一方法
        t1.start();
        t2.start();
    }
}

class Thread1 extends Thread
{
    public Thread1(String name)
    {
        super(name);
    }
    @Override
    public void run()
    {
        for(int i = 0; i < 100; i++)
            System.out.println("hello world:" + i);
    }
}

class Thread2 extends Thread
{
    public Thread2(String name)
    {
        super(name);
    }
    @Override
    public void run()
    {
        for(int i = 0; i < 100; i++)
            System.out.println("welcom:" + i);
    }
}

2、实现Runnable接口的类实现run方法

public interface java.lang.Runnable
{
    public abstract void run();
}
class MyThread implements Runnable
{
    @Override
    public void run()
    {
        ...
    }   
}
MyThread r = new MyThread();
Thread t = new Thread(r);
t.start();
/**
 * 通过定义实现Runnable接口的类实现线程
 * 本例创建了两个不同的线程
 *
 */
public class ThreadTest2
{
    public static void main(String[] args)
    {
        //构造一个实现了Runnable接口的匿名内部类
//      Thread thread = new Thread(new Runnable()
//      {   
//          @Override
//          public void run()
//          {
//              for(int i = 0; i < 100; i++)
//                  System.out.println("hello world:" + i);
//          }
//      });
        Thread t1 = new Thread(new MyThread());
        Thread t2 = new Thread(new MyThread2());
        
        System.out.println(t1.getName());
        System.out.println(t2.getName());
        
        t1.start();
        t2.start();
    }
}

class MyThread implements Runnable
{

    @Override
    public void run()
    {
        for(int i = 0; i < 100; i++)
            System.out.println("hello world:" + i);
    }
    
}

class MyThread2 implements Runnable
{

    @Override
    public void run()
    {
        for(int i = 0; i < 100; i++)
            System.out.println("welcom:" + i);
    }
    
}

3、总结

public class MyThread implements Runnable
{
    private boolean flag = true;
    public void run()
    {
        while(flag)
            {...}
    }
    public void stopRunnning()
    {flag = false;}
}

public class ControlThread
{
    private Runnnable r = new MyThread();
    private Thread t = new Thread(r);

    public void startThread()
    {t.start();}
    
    public void stopThread()
    {r.stopRunning();}
}
public class ThreadTest3
{
    public static void main(String[] args)
    {
        Runnable r = new HelloThread();
        
        Thread t1 = new Thread(r);
        Thread t2 = new Thread(r);
        
        t1.start();
        t2.start();
    }
}

class HelloThread implements Runnable
{
    //成员变量
    int i = 0;
    
    @Override
    public void run()
    {
        while(true)
        {
            System.out.println("number: " + i++);
            try
            {
                Thread.sleep((long)(Math.random() * 1000));
            }
            catch (InterruptedException e)
            {
                e.printStackTrace();
            }
            
            if (i == 5) 
            {
                break;
            }
        }
        
    }
    
}

输出结果为:


image.png

(2)局部变量:如果一个变量是局部变量,那么每个线程都会有一个该局部变量的拷贝,该局部变量的改变不会影响到其他线程。用下面例子的局部变量i加以说明:

public class ThreadTest3
{
    public static void main(String[] args)
    {
        Runnable r = new HelloThread();
        
        Thread t1 = new Thread(r);
        Thread t2 = new Thread(r);
        
        t1.start();
        t2.start();
    }
}

class HelloThread implements Runnable
{
    @Override
    public void run()
    {
        //局部变量
        int i = 0;
        
        while(true)
        {
            System.out.println("number: " + i++);
            try
            {
                Thread.sleep((long)(Math.random() * 1000));
            }
            catch (InterruptedException e)
            {
                e.printStackTrace();
            }
            
            if (i == 5) 
            {
                break;
            }
        }
        
    }
    
}

输出结果为:


image.png

三、线程的生命周期

1、线程的状态转换图

image.png

四、线程的优先级

1、线程的优先级及其设置

设置优先级是为了在多线程环境中便于系统对线程的调度,优先级高的线程将优先执行。
一个线程的优先级设置需要遵循以下原则:

2、线程的调度策略

线程调度器选择优先级高的线程运行。但是,如果发生以下情况,就会终止线程的运行。

上一篇下一篇

猜你喜欢

热点阅读