Java高级特性-多线程

进程
程序:对数据描述与操作的代码的集合
进程:是程序的一次动态执行过程,它对应了从代码加载、执行至执行完毕的一个完整过程。

进程的特点:
》进程是系统运行程序的基本单位
》每一个进程都有自己独立的一块内存空间、一组系统资源
》每一个进程的内部数据和状态都是完全独立的

进程包括:系统进程、用户进程

线程:
是进程中执行运算的最小单位,可完成一个独立的顺序控制流程。

多线程的好处:
》充分利用CPU资源
》简化编程模型
》带来良好的用户体验

Java中实现多线程
Thread类及其常用方法
》Thread() ---->分配新的Thread对象
》Thread(Runnable target) ---->分配新的Thread对象,target为run()方法被调用的对象
》Thread(Runnable target,String name) ---->分配新的Thread对象,target为run()方法被调用的对象,name为新线程的名字
》void run() ---->执行任务操作的方法
》void start() ---->使该线程开始执行,java虚拟机调用该线程的run()方法
》void sleep(long millis) ---->在指定的毫秒数内让当前正在执行的线程休眠
》String getName() ---->返回线程的名称
》int getPriority() ---->返回线程的优先级
》void setPriority(int newPriority) ---->更改线程的优先级
》static Thread currentThread() ---->返回当前正在执行的线程对象的引用
》boolean isAlive() ---->测试线程是否处于活动状态
》void join() ---->等待该线程终止
》void interrupt() ---->中断线程
》void yield() ---->暂停当前正在执行的线程对象,并执行其他线程

主线程:
在Java程序启动时,一个线程立即运行,该线程通常称为程序的主线程。

重要性:
》它是产生其他子线程的线程
》通常他必须最后完成执行,因为它执行各种关闭操作

主线程的引用通过调用currentThread()方法获得;
示例:
Thread t=Thread.currentThread();
System.out.println("主线程名---更改前---》"+t.getName());
t.setName("gaiming");
System.out.println("主线程名---更改后---》"+t.getName());

使用一个线程的步骤:
》定义一个线程,同时指明这个线程所要执行的代码,即期望完成的功能
》创建线程对象
》启动线程
》终止线程

创建线程类有两种方法:
继承Thread类、实现Runnable接口
区别:
继承Thread类:编写简单,可以直接操作线程,适用于单继承情况
实现Runnable接口:实现多个线程之间资源的共享;适用于多继承情况

》继承Thread类创建线程
示例:
public class DemoThraed extends Thread {
//重写run方法
    public void run() {
        //输出1~100的整数
        for (int i = 1; i <= 100; i++) {
            System.out.println("线程名----》"+Thread.currentThread().getName()+",整数---》"+i);//打印线程名和数字
        }
    }
    public static void main(String[] args) {
        DemoThraed demo=new DemoThraed();
        demo.start();//启动线程,java虚拟机调用该线程的run()方法
    }
}

线程实例调用start()和直接调用run()的区别:
调用start()表示该线程处于启动状态,等待操作系统分配资源执行run()方法中的代码,多个线程同时处于启动状态时,线程交替执行。
直接调用run()方法和之前学过的直接调用实例方法没有区别,程序是按顺序执行的,属于单线程执行模式。

示例:start()启动两个线程,交替执行
public class DemoThraed extends Thread {
//重写run方法
    public void run() {
        //输出1~100的整数
        for (int i = 1; i <= 100; i++) {
            System.out.println("线程名----》"+Thread.currentThread().getName()+",整数---》"+i);//打印线程名和数字
        }
    }
    public static void main(String[] args) {
        DemoThraed demo1=new DemoThraed();
        DemoThraed demo2=new DemoThraed();
        demo1.start();//启动线程
        demo2.start();
    }
}
示例:调用run(),顺序执行
public class DemoThraed extends Thread {
//重写run方法
    public void run() {
        //输出1~100的整数
        for (int i = 1; i <= 100; i++) {
            System.out.println("线程名----》"+Thread.currentThread().getName()+",整数---》"+i);//打印线程名和数字
        }
    }
    public static void main(String[] args) {
        DemoThraed demo1=new DemoThraed();
        DemoThraed demo2=new DemoThraed();
        demo1.run();//调用方法
        demo2.run();
    }
}

》实现Runnable接口创建线程
示例:
public class DemoThraed implements Runnable {
    // 实现run()方法,
    @Override
    public void run() {
        // 输出1~100的整数
        for (int i = 1; i <= 100; i++) {
            System.out.println("线程名----》" + Thread.currentThread().getName() + ",整数---》" + i);// 打印线程名和数字
        }
    }
public static void main(String[] args) {
    //实例化DemoThraed对象
    DemoThraed demo=new DemoThraed();
    //创建Thread对象,并把DemoThraed对象作为参数入参
    Thread thread=new Thread(demo);
    //调用Thread对象的start()方法启动线程
    thread.start();
}
}

线程的状态:
创建、就绪、运行、阻塞、死亡

使线程暂停执行的条件:
》优先级较低
》sleep()方法休眠
》wait()方法等待
》yield()方法让出CPU控制权
》线程由于等待一个文件,I/O事件被阻塞

示例:
public class DemoThraed implements Runnable {
    // 实现run()方法,
    @Override
    public void run() {
        System.out.println("线程在运行");
        // 输出1~100的整数
        for (int i = 1; i <= 100; i++) {
            System.out.println("线程名----》" + Thread.currentThread().getName() + ",整数---》" + i);// 打印线程名和数字
        try {
            Thread.sleep(2000);
            System.out.println("2秒后重新运行");
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        }
    }
public static void main(String[] args) {
    //实例化DemoThraed对象
    DemoThraed demo=new DemoThraed();
    //创建Thread对象,并把DemoThraed对象作为参数入参
    Thread thread=new Thread(demo);
    System.out.println("线程为新建");
    //调用Thread对象的start()方法启动线程
    thread.start();
    System.out.println("线程为就绪");
}
}

线程的优先级:(优先级高的线程先执行的概率高)
线程的优先级用1~10表示,1表示优先级最低,10表示优先级最高,默认值为5.
示例:
public class DemoThraed implements Runnable {
    // 实现run()方法,
    @Override
    public void run() {
        // 输出1~100的整数
        for (int i = 1; i <= 100; i++) {
            System.out.println("线程名----》" + Thread.currentThread().getName() + ",整数---》" + i);// 打印线程名和数字
        }
        }
public static void main(String[] args) {
    //实例化DemoThraed对象
    DemoThraed demo=new DemoThraed();
    //创建Thread对象,并把DemoThraed对象作为参数入参
    Thread thread1=new Thread(demo);
    Thread thread2=new Thread(demo);
    thread1.setPriority(Thread.MAX_PRIORITY);
    thread2.setPriority(Thread.MIN_PRIORITY);
    //
    System.out.println("线程1的优先级"+thread1.getPriority());
    System.out.println("线程2的优先级"+thread2.getPriority());
    System.out.println("******************************************");
    //调用Thread对象的start()方法启动线程
    thread1.start();
    thread2.start();
    
}
}

线程的强制运行
join()方法使当前线程暂停执行,等待调用该方法的线程结束后再继续执行本线程。

线程的礼让:
yield()方法可暂停当前线程执行,允许其他具有相同优先级的线程获得运行机会,该线程处于就绪状态,不转为阻塞状态。若无其他相同或更高优先级的线程,则该线程继续执行。

线程同步的实现:
当两个或多个线程需要访问同一资源时,需要以某种顺序来确保该资源某一时刻只能被一个线程使用,这就称为线程同步。

有两种方式:同步方法、同步代码块

》同步方法
使用synchronized修饰方法
示例:
public class Site implements Runnable{
    private int count=10;//记录剩余票数
    private int number=0;//记录买到第几张
    private boolean flag=false;//记录是否售完
    
    @Override
    public void run() {
        while(!flag) {
            sale();
        }
        
    }
    //售票方法
    synchronized public void sale() {
        if (count<=0) {
            flag=true;
            return;
        }
        //1.修改数据
        number++;
        count--;
        try {
            Thread.sleep(500);//模拟网络延迟
        } catch (Exception e) {
            // TODO: handle exception
        }
        //显示信息
        System.out.println(Thread.currentThread().getName()+"抢到第"+number+"张票,"+"剩余"+count+"张票");
    }
    public static void main(String[] args) {
        Site site=new Site();
        Thread thread1=new Thread(site);
        Thread thread2=new Thread(site);
        Thread thread3=new Thread(site);
        thread1.setName("逃泡泡");
        thread2.setName("黄牛");
        thread3.setName("代理");
        thread2.setPriority(7);
        thread3.setPriority(8);
        thread1.start();
        thread2.start();
        thread3.start();
    }

}

》同步代码块
使用synchronized修饰的代码块
语法:
synchronized(){
//需要同步的代码
}

优点:可以针对任意代码块,可以任意指定上锁的对象,因此灵活性更高

示例:
public class Site implements Runnable {
    private int count = 10;// 记录剩余票数
    private int number = 0;// 记录买到第几张
    private boolean flag = false;// 记录是否售完

    @Override
    public void run() {
        while (!flag) {
            synchronized (this) {
                if (count <= 0) {
                    flag = true;
                    return;
                }
                // 1.修改数据
                number++;
                count--;
                try {
                    Thread.sleep(500);// 模拟网络延迟
                } catch (Exception e) {
                    // TODO: handle exception
                }
                // 显示信息
                System.out.println(Thread.currentThread().getName() + "抢到第" + number + "张票," + "剩余" + count + "张票");

            }
        }

    }

    public static void main(String[] args) {
        Site site = new Site();
        Thread thread1 = new Thread(site);
        Thread thread2 = new Thread(site);
        Thread thread3 = new Thread(site);
        thread1.setName("逃泡泡");
        thread2.setName("黄牛");
        thread3.setName("代理");
        thread2.setPriority(7);
        thread3.setPriority(8);
        thread1.start();
        thread2.start();
        thread3.start();
    }
}

-----------------------------
线程安全的类型
一个类在被多个线程访问时,不管运行环境执行这些线程有什么样的时序安排,他必须以固定的、一致的顺序执行。这样的类型称为线程安全的类型。

Hashtable和HashMap
》继承关系不同
两者都实现了Map接口,Hashtable继承了Dictionary类,HashMap继承了AbstractMap类

》是否线程安全
Hashtable是线程安全的,其中的方法是同步的
HashMap中的方法在默认情况下是非同步的

》是否允许出现null值
Hashtable中的键和值都不允许为null
HashMap中,null可以作为键也可以作为值

》效率比较
HashMap重速度,轻安全。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值