黑马程序员——Java基础--多线程(一)

来源:互联网 发布:电子标书的软件 编辑:程序博客网 时间:2024/06/10 18:20

-----------android培训java培训、java学习型技术博客、期待与您交流!------------

第五讲 多线程(一)

一、 概述

        线程,我们都知道有单线程和多线程俩种,当然由线程我们会引出一种方式叫做进程,什么又叫进程呢?就是一个正在运行的程序,简单的说就是打开任务管理器,我们可以看到很多进程,这就是进程,而线程则是指一个程序内部的执行的一条线,也可以说是独立运行的单元,在我们生活中有很多多线程的例子,比如说12306的购票系统就是多线程的,这样一来是系统为了给我们提供方便。

       在Java语言中,线程的调度分为两种,分别是分时调度和抢占式调度,对于我们CPU而言,它对我们系统的进程控制是轮流进行的,所以会存在程序开多了电脑运行会变慢,这就是属于分时调度的,而JVM是属于抢占式的。

二、多线程的俩种主要创建方式

我们可以通过案例来说明。

1、继承Thread类

        线程对象描述类,java.lang.Thread
    步骤:
        1、定义类继承Thread
        2、该子类重写Thread的run()方法
        3、创建Thread子类对象
        4、调用Thread的方法start()
    每个线程都有自己的名字:Thread-0,-1,-2...
    获取线程名:1、Thread类方法 String getName(),2、在Thread类,有一个静态方法currentThread()返回当前正在运行的线程对象Thread.currentThread()。
    设置线程名字:1、Thread类的setName(String name)。
                2、Thread类的构造方法
    线程的优先级:每个线程都有自己的优先级(1-10),优先级高,占用CPU的时间相对要多一些,(线程默认优先级为5)。
    线程控制:
    就绪状态和阻塞的区别:前者有执行资格,又叫临时阻塞,后者没有。

package cn.itheima.thread;/* * 继承Thread类: * 1、定义一个类 * 2、重写Thread中的run()方法 * 3、创建一个线程 * 4、调用线程的start()方法 * 5、执行语句输出 */public class ThreadDemo {public static void main(String[] args) {Test t = new Test();//创建一个线程t.start();//调用线程的start()方法for (int i = 0; i < 50; i++) {System.out.println("helloworld!"+i);}}}//定义一个类class Test extends Thread{public void run(){//重写run()方法for (int i = 0; i < 50; i++) {System.out.println("Test 运行效果:"+i);}}}

部分结果:

Test 运行效果:34
helloworld!43
Test 运行效果:35
helloworld!44
Test 运行效果:36
helloworld!45
Test 运行效果:37
helloworld!46
helloworld!47

我们可以明显的看到JVM在运行的时候属于抢占式的

2、实现runnable接口的创建

        实现接口方式 java.lang.Runnable
    步骤:
        1、定义类,实现Runnable接口
        2、重写run()方法
        3、创建Thread类对象,在Thread类的构造方法中,传递Runnable接口实现类对象
        4、调用Thread 的 start()

package cn.itheima.thread;/* * 继承Thread类: * 1、定义一个实现Runnable的接口类 * 2、覆盖Runnable中的run()方法 * 3、把实现类的对象传入Thread的构造方法 * 4、调用线程的start()方法 * 5、执行语句输出 */public class ThreadDemo1 {public static void main(String[] args) {Thread  t = new Thread(new Test1());//把实现类的对象传入Thread的构造方法t.start();//调用线程的start()方法for (int i = 0; i < 50; i++) {System.out.println("helloworld!"+i);}}}//定义一个类class Test1 implements Runnable{public void run(){//覆盖run()方法for (int i = 0; i < 50; i++) {System.out.println("Test1 运行效果:"+i);}}}

部分结果:

Test1 运行效果:39
helloworld!35
Test1 运行效果:40
helloworld!36
Test1 运行效果:41
helloworld!37
helloworld!38

俩种方式的对比:

    继承Thread,单继承,继承的方式,线程中数据被单个线程独享
    实现Runnable接口,避免了单继承的局限性,线程中的数据被共享

三、线程中的安全问题

    必须解决,(速度会变慢)
    同步技术:出现目的,解决线程操作共享数据的安全问题,关键字,synchronized
    格式:
        synchronized(任意对象){
            线程操作的所有共享数据
        }
    平衡,速度和安全上,保证安全,牺牲速度
    任意对象:监视器-->同步锁-->锁
    线程运行到同步代码块的时候,先判断,这个锁还有没有,如果没有,只能等在外面,如果有,线程就获取到这个对象锁,进入同步运行,线程出去同步代码块后,对象锁在交还回去。
    同步方法:synchronized加在方法的返回值类型前面,同步方法只能被一个线程调用,不调用完,其他线程不能用,有锁,本类的对象引用this。
    静态的同步方法中肯定有锁,锁必须是对象,对象就是自己类的class文件被JVM创建出来的这个对象。
    任何一个数据类类型,JVM都会赋予它一个特别的属性,class 是关键字
    静态方法中的同步锁,就是自己本类.class属性

示例:火车票售票窗口

package cn.itheima.thread;/* *  多线程技术,实现售票的案例 *   一共100张,分成3个窗口出售,3个线程共同出售100张 */class Lei implements Runnable {private static int tickets = 100;private Object obj = new Object();public void run() {while (true) {synchronized (obj) {if (tickets > 0) {System.out.println(Thread.currentThread().getName()+ "号窗口出售第--" + tickets--);}}}}}public class RunnableTest {public static void main(String[] args) {Lei lei = new Lei();Thread t0 = new Thread(lei);Thread t1 = new Thread(lei);Thread t2 = new Thread(lei);t0.start();t1.start();t2.start();}}

示例2: 多线程技术,模拟储户在银行存钱

package cn.itheima.thread;import cn.itheima.thread.Bank;import cn.itheima.thread.Customer;/* *  要求: *    多线程技术,模拟储户在银行存钱 *    每次存储100元,分别在两个窗口存,每个窗口存3次 *    余额是0 *      存储的时候余额变化 *        100 200 300 400 500 600 *    一个是银行  存钱的功能   *    一个储户,调用银行的存钱功能,参数 *     *   方法add 代码全是线程共享数据 *   同步整个方法  synchronized加在方法的声明上 */class Bank{private static int sum = 0;//private Object obj = new Object();public static synchronized void add(int money){//synchronized(Bank.class){sum = sum + money;System.out.println(sum);//}}}class Customer implements Runnable{private Bank b = new Bank();public void run(){for(int x = 0 ; x < 3 ; x++){b.add(100);}}}public class ThreadDemo1 {public static void main(String[] args) {Customer c = new Customer();Thread t0 = new Thread(c);Thread t1 = new Thread(c);t0.start();t1.start();}}


-----------android培训java培训、java学习型技术博客、期待与您交流!------------

 

 

0 0