一 线程的基本实现
进程是一段正在执行的程序代码,线程一个类(实质还是代码),线程是进程的进一步划分。一个系统能同时执行多个进程,一个进程可以同时执行多个线程
1. 继承Thread类
- 定义的新类必须要继承Thread类才能算作进程类
- 在进程类中要重载run()方法(该方法里面存放的便是线程主体)
- 启动该进程,需要在main函数中实例化进程类MyThread,然后调用从Thread类中继承来的start(方法),实例代码如下:
MyThread1 c=new MyThread1("Thread C");
MyThread1 d=new MyThread1("Thread D");
c.start();
d.start()
- 直接调用run方法是无法实现同步进行的,只是顺序执行了该方法中的代码而已。
- 通过继承Thread类来实现的进程类,只能调用一次start方法,再调用会报错。但是Thread类本身可以对同一进程进行多次调用start方法(即实现了多线程资源的共享,前提是该进程类实现了接口,而不是继承了Thread类)。如:
MyThread1 c=new MyThread1("Thread C");
c.start();
c.start();
会报错,但下面的可:
MyThread3 e=new MyThread3();
// new Thread(e).start();
// new Thread(e).start();
Thread te=new Thread(e);
Thread tf=new Thread(e);
te.start();
tf.start();
2. 实现Runnable接口
- 新类要实现Runnable接口
- 重载run方法—实现自己想写的进程
- 在main函数中开启进程同样需要通过Thread类中的start()方法,可是它没有继承Thread类,自然无法直接使用Thread类的start()方法,我们需要先实例化对象,然后,实例化Thread类的对象,将原对象作为构造方法的参数传入,然后调用Thread类的start()方法
MyThread0 a=new MyThread0("Thread A");
MyThread0 b=new MyThread0("Thread B");
Thread ta=new Thread(a);
Thread tb=new Thread(b);
ta.start();
tb.start();
二 进程Thread类的相关方法
- 两种创建进程方法的命令方式不同,继承Thread类的类要调用super方法来调用Thread类的构造方法;实现Runnable接口的类也要调用Thread类的构造方法。
- Thread类的sleep方法中,传入参数以毫秒为单位
- main方法也是一个线程,主线程可能比其他线程先执行完(因为线程的进行无视代码顺序)
- **所谓线程优先级,**个人理解只是对资源竞争的一个辨别依据,就是说当多个线程竞争资源时,具有较高优先级的线程会优先执行。
楼主的线程执行过程太短、逻辑太简单,基本不存在竞争问题,当然看不出优先级的作用……
其实所谓优先级只有在长期稳定运行的系统中才有用,这个很难测试的 - 线程的礼让如何理解
- 实现接口的进程可对同一资源共同操作
三 同步与死锁
- 同步有两种代码块和同步方法两种方式—为了解决共享资源的同步问题–同步方法是锁上调用该方法的那个实例化类对象;同步代码块是锁上某对象
- 同步代码块就是对某对象上锁,不开锁不能执行下面的代码块
- 死锁就是在同步代码块中嵌套同步代码块
- 生产消费商品的实例
- object的等待与唤醒方法(wait,notify)可以用来确保进程不同时执行,实现了进程实现的互不干扰与一定的完整性(等A做完一部分,B再对A做完的那部分进行操作)–否则可能对同一数据,多次读取
- 同步是为了防止在生产一半时,被取出,发生配对错误
- 自定义stop方法,设置标志位,来终止进程。而不是通过Thread自带的stop方法,因为可能会发生死锁问题