java基础3:多线程

关于Java基础的文章,我觉得写得还可以,以前发在了我其它的博客了,肯定是原创,现在再分享给大家出来。

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

  如果一次只完成一个事情,还是比较容易实现的,但事实上很多事情都是同时执行的,java为了模拟这种状态,引入了线程机制。

当程序同时完成多个事情时,就是所谓的多线程程序。

  在一个时刻,单核的cpu只能运行一个程序。而我们看到的同时运行效果,只是cpu在多个进程间做着快速的随机切换动作。

  所以说多线程解决了多部分同时运行的问题,但是线程太多的话肯定会影响效率。

  首先老规矩一张图来展现我们本次要介绍的内容:

一、实现方式

实现线程的方式一共有两种---继承Thread类和实现Runnable接口。

1、继承Thread类。

a、定义类继承Thread。

b、复写Thread中的run方法。

c、创建定义类的实例对象。

d、调用start方法启动线程。

class TestThread extends Thread            // a、定义类继承Thread。
{
    public void run()                    //b、复写Thread中的run方法。
    {
        for (int x = 0; x < 50 ;x++ )
        {
            System.out.println(Thread.currentThread().getName()+"......"+x);
        }
    }
}

class Demo
{
    public static void main(String[] args)
    {
        TestThread t1= new TestThread();//c、创建定义类的实例对象。
        TestThread t2= new TestThread();
        t1.start();                    //d、调用start方法启动线程。
        t2.start();
    }
}

2、实现runnable接口

  a、定义类实现Runnable的接口。

b、覆盖Runnable接口中的run方法。

c、通过Thread类创建线程对象。

d、调用start方法启动线程。

class TestThread implements Runnable            //a、定义类实现Runnable的接口。
{
	public void run()				// b、覆盖Runnable接口中的run方法。
	{
		for (int x = 0; x < 50 ;x++ )
		{
			System.out.println(Thread.currentThread()+"++++++"+x);
		}
	}
}
class Demo
{
	public static void main(String[] args)
	{

		TestThread d = new TestThread();
		Thread t1 = new Thread(d);
		Thread t2 = new Thread(d);		//c、通过Thread类创建线程对象。
		t1.start();			     //d、调用start方法启动线程。
		t2.start();
	}
}

3、实现Runnable接口的优势

  实际开发中,我们经常使用第二种方式做多线程,它的优势在于

  a、避免了按照面向对象的思想将任务封装成对象。

  b、避免了java单继承的局限性。

二、线程的生命周期

线程具有生命周期,其各个生命周期的关系如下图。

三、线程安全

  实际开发中,使用多线程的情况有很多,比如火车站售票系统,当有多个线程做取票动作时,假设此时只有一张票,一线程将票售出,此时二线程完成了判断是否有票动作,并得出票数大于0结论。此时执行售票就会产生负数。

1、安全问题产生的原因

  a、多个线程在操纵共享数据

  b、操纵共享数据的代码有多条。

2、解决办法--同步

  将多条操作共享数据的线程代码封装起来,当有线程执行这些代码时候,其他线程不可参与。

  a、同步代码块

  
synchronized(obj)
{
  //需要同步的代码
}

  b、同步函数

public synchronized void show()
{
        //需要同步的代码
}

3、同步函数和同步代码块的区别

  同步函数的锁是this

  同步代码块的锁是任意的(也可以是this)

  实际开发中建议用同步代码块。

4、同步的利弊

好处:解决了多线程的安全问题。

弊端:多个线程需要判断锁,较为消耗资源。

5、静态函数代码块

  如果同步函数被静态修饰后,使用的锁是什么呢?设计模式中的单例模式给大家展示。

//懒汉式
class Single
{
    private static Single s = null;

    private Single(){}

    public static Single getInstance()
    {
        if(s == null)
        {
            synchronized(Single.class)    //静态方法写---类名.class
            {
                if(s==null)
                    s = new Single();
            }
        }
        return s;
    }
}
 

四、线程间通信

线程间的通信其实就是多个线程共享同一个资源。

class  ResorceDemo
{
    public static void main(String[] args)
    {
        Resorce r = new Resorce();
        Input in = new Input(r);
        Output out = new Output(r);
        Thread t1 = new Thread(in);
        Thread t2 = new Thread(out);
        t1.start();
        t2.start();
    }
}
class Resorce //定义一个资源
{
    String name;
    String sex;
    boolean flag = false;
}

class Input implements Runnable
//写入资源
{
    Resorce r;
    Input(Resorce r)
    {
        this.r = r;
    }
    public void run()//复写run方法
    {
        int x = 0;//x相当于一个标志.
        while (true)
        {
            synchronized(r)
            {
                if (r.flag == true)
                {
                    try
                    {
                        r.wait();
                    }
                    catch (InterruptedException e)
                    {
                    }

                }
                else
                {
                    if (x==0)
                    {
                        r.name = "mike";
                        r.sex = "nan";
                    }
                    else
                    {
                        r.name = "傻妞";
                        r.sex = "妞妞妞妞i牛i牛ii牛";
                    }
                    r.flag = true;
                    r.notify();//唤醒
                }
                    x = (x+1)%2;//x在0和1之间相互交替.

            }
        }
    }
}
class Output implements Runnable
//读取资源
{
    Resorce r;
    Output(Resorce r)
    {
        this.r = r;
    }
    public void run()
    {
        while (true)//无限循环
        {
            synchronized(r)
            {
                if (r.flag == false)
                {
                    try
                    {
                        r.wait();
                    }
                    catch (InterruptedException e)
                    {
                    }

                }
                else
                {
                    System.out.println(r.name + "..."+r.sex);
                    r.flag = false;
                    r.notify();
                }

            }

        }
    }
}

五、常见操作方法

1,wait(): 让线程处于冻结状态,被wait的线程会被存储到线程池中。

2,notify():唤醒线程池中一个线程(任意).

3,notifyAll():唤醒线程池中的所有线程。

4,setPriority():设置优先级

5,yield():暂停当前线程,让其他线程执行。

当然,这些常见的操作方法在API中都可以查到,这不是我要说的重点,下面来对这些方法做一下比较。

(1)wait 和 sleep 区别?

  1,wait可以指定时间也可以不指定。    sleep必须指定时间。

  2,在同步中时,对cpu的执行权和锁的处理不同。  wait:释放执行权,释放锁。  sleep:释放执行权,不释放锁。

(2)wait(),notify(),notifyAll(),用来操作线程为什么定义在了Object类中?

a,这些方法存在与同步中。

b,使用这些方法时必须要标识所属的同步的锁。同一个锁上wait的线程,只可以被同一个锁上的notify唤醒。

c,锁可以是任意对象,所以任意对象调用的方法一定定义Object类中。

六、总结

多线程本身也是比较复杂的问题,要完全理解它还需要时间,所谓孰能生巧,这些知识还是要多看多练多去实践才能真正掌握。

时间: 2024-10-08 00:30:38

java基础3:多线程的相关文章

【BigData】Java基础_多线程

所谓的多线程就像小吃街卖铜锅米线的老板,老板就好比一个操作系统,如果5个顾客同时去买米线,那么,此时老板就会同时准备好5个铜锅,然后同时放上水.调料.米线,同时煮5个人的米线,如果逐个煮的话,那么估计煮了2个人的米线,后面3人就来找老板退款了. 官方解释:多线程(英语:multithreading),是指从软件或者硬件上实现多个线程并发执行的技术 在Java中实现多线程四部曲: (1)将需要用多线程方式执行的逻辑,写入一个runnable实现类中(run方法中): (2)创建出这个runnabl

Java基础4——多线程

线程依赖于进程而存在 进程:正在运行的程序 是操作系统进行资源分配和调度的独立单位 每个进程都有自己的内存空间和系统资源 多进程的意义:单进程的计算机只能做一件事情 DOS窗口就是典型的单进程 多进程的计算机可以在一个时间段内执行多个任务 单核CPU在某个时间点只能执行一件事情,事实上CPU一直在高效切换各个进程 线程:一个进程内可以执行多个任务,每个任务可以看成是一个线程,线程是程序(进程)的执行单元或执行路径,是程序使用CPU的最小单位 多线程的意义:提高应用程序的使用率 程序的执行都是在抢

3.8 java基础总结①多线程

多线程 多线程这章理论大于实践,因为在实际开发中多线程的都封装到框架里边了的,程序员一般不会写多线程,多线程属于Java里边比较底层的代码了. 线程是处理器调度的最基本单位程序>进程>线程程序是死的,当启动程序得时候会有一个或几个进程,每个进程里边可以有诺干线程.基于线程开销更 创建线程:两种方法1.声明Thread的子类,重写run方法class MyThread extends Thread{ public void run(){ }}Mythread a = new MyThread()

Java基础知识—多线程编程(五)

概述 Java 给多线程编程提供了内置的支持.一个多线程程序包含两个或多个能并发运行的部分.程序的每一部分都称作一个线程,并且每个线程定义了一个独立的执行路径.使用多线程也是为了充分的利用服务器资源,提高工作效率. 线程生命周期 线程是一个动态执行的过程,它也有一个从产生到死亡的过程. 新建状态: 使用 new 关键字和 Thread 类或其子类建立一个线程对象后,该线程对象就处于新建状态.它保持这个状态直到程序 start() 这个线程. 就绪状态: 当线程对象调用了start()方法之后,该

java基础之多线程

参考博客 http://www.mamicode.com/info-detail-517008.html 1.进程和线程的区别 进程:每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进程包含1--n个线程. 线程:同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换开销小. 线程和进程一样分为五个阶段:创建.就绪.运行.阻塞.终止. 多进程是指操作系统能同时运行多个任务(程序). 多线程是指在同一程序中有多个顺序流在执行. 2.实现R

java基础及多线程

1.多线程 1.1.进程与线程 ? 进程就是一个运行中的程序. ? 一个进程中可以有多个线程,线程是CPU调度和分派的基本单位.我们可以理解为线程就是程序运行中的一条路径. 1.2.多线程的创建及使用 1.2.1.创建 自定义一个类继承Thread类或实现Runnable接口 1.2.2:两种创建多线程的区别 继承Thread类:Thread()或Thread(String name) 多个线程分别完成自己的任务 实现Runnable接口:Thread(Runnable target) 或Thr

java基础07 多线程

在学习操作系统时,我们会学习进程和线程,那么进程和线程又是什么东西呢? 进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位. 线程(thread)是操作系统能够进行运算调度的最小单位. 它被包含在进程之中,是进程中的实际运作单位. 一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务. Java程序运行原理 java 命令会启动 java 虚拟机,启动 JVM,等于启动了一个应用程序,也就是启动了一

黑马程序员-Java基础之多线程

多线程 进程:正在进行中的程序.其实进程就是一个应用程序运行时的内存分配空间. 线程:其实就是进程中一个程序执行控制单元,一条执行路径.进程负责的是应用程序的空间的标示.线程负责的是应用程序的执行顺序. 一个进程至少有一个线程在运行,当一个进程中出现多个线程时,就称这个应用程序是多线程应用程序,每个线程在栈区中都有自己的执行空间,自己的方法区.自己的变量. jvm在启动的时,首先有一个主线程,负责程序的执行,调用的是main函数.主线程执行的代码都在main方法中. 当产生垃圾时,收垃圾的动作,

Java基础总结--多线程总结2

----多线程通信-----1.概述:多个线程处理同一个资源,但是各自的任务不相同eg:线程1负责存储数据,线程2负责处理该数据.数据--就是同一个资源怎样用java语言描述上面的例子:* 资源是变化的--数据是变化的--将其封装为对象* 存在两个任务不同的线程,需要2个run方法--所以封装在两个不同的线程类中* 必须保证输入和输出处理的是同一个对象-输入输出构造方法传参数(参数为资源对象引用)* 主函数里面,创建资源对象,线程类对象,启动线程2.多线程通信依然会出现线程安全的问题解决办法--

【黑马程序员】-Java基础学习-多线程

------- android培训.java培训.期待与您交流! --------- 首先讲一下进程和线程的区别: 进程:每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进程包含1--n个线程. 线程:同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换开销小. 线程和进程一样分为五个阶段:创建.就绪.运行.阻塞.终止. 多进程是指操作系统能同时运行多个任务(程序). 多线程是指在同一程序中有多个顺序流在执行.