多线程
线程调度
- 分时调度
- 抢占调度(java)
主线程
main方法
创建线程类
一:创建类继承thread类
1. 创建thread类的子类
2. 在子类中重写thread类中run方法
(我觉得这个run相当于main方法),设置线程任务
3. 创建thread子类对象
4. 调用thread类中start方法,开启新线程,执行run方法,
不可以多次调用一个线程
MyThread myThread = new MyThread();
myThread.start();
public class MyThread extends Thread{
@Override
public void run() {}
}
二:实现runnable接口,重写run方法
1. 创建实现类
2. 重写run方法
3. 创建runnable实现类对象
4. 创建Thread对象,构造中传递runnable实现类对象
5. 开启线程
public class Runnableimpl implements Runnable {
@Override
public void run() {
}
Runnable runnable = new RunnableImpl();
Thread th = new Thread(runnable);
th.start();
两者区别
实现runnable:避免继承的局限(只有一个继承)
增强程序扩展性,增强耦合性
Thread类
- getName():获取线程名称
- currentThread():获取当前线程对象
Thread.currentThread().getName();//-->获取线程名称
-
setName(str):设置线程名称
-
Threa(str):在线程类中使用thread构造来设置线程名称
-
sleep():线程阻塞
Thread.sleep(num);暂停num秒
线程安全
同步代码块
public void run(){
synchronized(锁对象){
xxx
}
}
//任意对象都可以
//各个线程的锁对象是一个
同步方法
public void run(){
xxx
method();
}
public synchronized void method(){
xxx
}
lock锁
是一个接口,reentrantlock为实现类
Lock lock = new reentrantlock();
public void run(){
lock.lock();
try{
xxx//安全问题算法
}catch(exception e){
xxx
}finally{
lock.unlock();
}
}
线程通信
线程同步
生产者消费者问题
生产者
继承Thread类–》做构造,在构造里传入资源对象–》在run方法中判断资源,如果有资源,就wait待唤醒,唤醒后,进行生产资源–》修改资源属性使其为“有”,再进行唤醒
private Source sou;
public Product(Source sou)
{
this.sou =sou;
}
@Override
public void run(){
while (true){
synchronized (sou){
if (sou.b){
try {
sou.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
sou.name="nihao";
System.out.println("正在"+sou.name);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
sou.b=true;
sou.notify();
System.out.println("ok");
}
}
}
消费者
- 继承Thread类
- 声明资源属性,创建构造,在构造中传入资源对象
- 在run方法中,设置同步代码块,传入资源对象
- 判断资源,如果没有则阻塞,wait
- 唤醒后,进行消费
- 消费后,修改资源属性,使其为“没有”。
- 再唤醒,使生产者进行生产
private Source sou;
Consumer(Source sou){
this.sou =sou;
}
@Override
public void run() {
while (true){
synchronized (sou){
if (!sou.b)
{
try {
sou.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("使用资源"+sou.name);
sou.b=false;
sou.notify();
System.out.println("资源"+sou.name+"用完了");
}
}
}
主类
创建资源对象,创建生产者对象,消费者对象,在创建时,传入资源对象,分别调用start
public class DemoMain {
public static void main(String[] args) {
Source sou = new Source();
new Product(sou).start();
new Consumer(sou).start();
}
}
线程池
一个存放线程对象的容器,一般用集合linkedlist。
- 使用工厂类Executors的newFixedThreadPool方法,创建线程池,返回executorService对象
- 创建类实现runnable接口,设置线程任务
- 调用ExecutorService中submit方法,传递线程任务
ExecutorService es = Executors.newFixedThreadPool(4);
es.submit(new MyThread());
es.submit(new MyThread());
es.submit(new MyThread());
class Mythread implements Runnable{
@override
public void run(){
xxx
}
}