首页 > 黑马程序员5 多线程

黑马程序员5 多线程

------- android培训、java培训、期待与您交流! ----------

创建线程的第一种方式:继承Thread类。

步骤:

1,定义类继承Thread。

2,复写Thread类中的run方法。

目的:将自定义代码存储在run方法。让线程运行。

3,调用线程的start方法,

该方法两个作用:启动线程,调用run方法。

创建线程的第二种方式:实现Runable接口

步骤:

1,定义类实现Runnable接口

2,覆盖Runnable接口中的run方法。

将线程要运行的代码存放在该run方法中。

3,通过Thread类建立线程对象。

4,将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数。

为什么要将Runnable接口的子类对象传递给Thread的构造函数。

因为,自定义的run方法所属的对象是Runnable接口的子类对象。

所以要让线程去指定指定对象的run方法。就必须明确该run方法所属对象。

5,调用Thread类的start方法开启线程并调用Runnable接口子类的run方法。

实现方式和继承方式有什么区别呢?

实现方式好处:避免了单继承的局限性。

在定义线程时,建立使用实现方式。

两种方式区别:

继承Thread:线程代码存放Thread子类run方法中。

实现Runnable,线程代码存在接口的子类的run方法。

范例:

public class Test1 {public static void main(String[] args) {for(int i=0;i<3;i++){new Thread(new Mess()).start();}}
}class Mess implements Runnable{private static int taskcount = 0;private final int id = taskcount ++;Mess(){System.out.println("new message"+id);}@Overridepublic void run() {System.out.println("r1:"+id);Thread.yield();  //对线程调度器的一种建议System.out.println("r2:"+id);Thread.yield();System.out.println("r3:"+id);Thread.yield();System.out.println("end"+id);}
}

=========================================================

Java对于多线程的安全问题提供了专业的解决方式。

就是同步代码块。

synchronized(对象)

{

需要被同步的代码

}

对象如同锁。持有锁的线程可以在同步中执行。

没有持有锁的线程即使获取cpu的执行权,也进不去,因为没有获取锁。



同步规则(何时使用同步):如果正在写一个变量,他可能接下来被另一个线程读取,或者正在读取一个上一次已经被另一个线程写过的变量,必须使用同步,并且,读写线程都必须用相同的监视器锁同步。



同步函数的锁是this

静态同步函数的锁是Class对象。

 

public class Test1 {public static void main(String[] args) {for(int i=0;i<3;i++){new Thread(new Mess()).start();}}
}class Mess implements Runnable{private static int taskcount = 0;private final int id = taskcount ++;Mess(){System.out.println("new message"+id);}@Overridepublic void run() {System.out.println("r1:"+id);Thread.yield();  //对线程调度器的一种建议System.out.println("r2:"+id);Thread.yield();System.out.println("r3:"+id);Thread.yield();System.out.println("end"+id);}
}

=======================================================

等待/唤醒机制

涉及的方法:

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

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

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

这些方法都必须定义在同步中,因为这些方法是用于操作线程状态的方法,

必须要明确到底操作的是哪个锁上的线程。

为什么操作线程的方法 wait、notify、notifyAll定义在了Object类中?

因为这些方法是监视器的方法,监视器其实就是锁。

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

========================================================

Lock接口

将同步和锁封装成了对象,并将操作锁的方式定义到了该对象中,将隐式动作变成了显式动作。

Lock lock=new ReentrantLock();

lock.lock();//获取锁

code...;//throw Exception();

lock.unlock();//释放锁

try

{

lock.lock();//获取锁

}

finally

{

lock.unlock;//释放锁

}

Lock接口:它的出现替代了同步代码块或者同步函数。将同步的隐式锁操作变成了显式锁操作;

同时更为灵活,可以一个锁上加上多组监视器。

lock();获取锁

unlock();释放锁,通常需要定义到finally代码块中。

Condition接口:它的出现替代了Object中的wait、notify、notifyAll方法。

将这些监视器方法单独进行了封装,变成了Condition监视器对象,

可以和任意锁组合。

await();//等待

signal();//唤醒一个等待线程

signalAll();//唤醒所有等待线程

import java.util.concurrent.locks.*;class ProducerConsumerDemo2 
{public static void main(String[] args) {Resource r = new Resource();Producer pro = new Producer(r);Consumer con = new Consumer(r);Thread t1 = new Thread(pro);Thread t2 = new Thread(pro);Thread t3 = new Thread(con);Thread t4 = new Thread(con);t1.start();t2.start();t3.start();t4.start();}
}
class Resource
{private String name;private int count = 1;private boolean flag = false;//  t1    t2private Lock lock = new ReentrantLock();private Condition condition_pro = lock.newCondition();private Condition condition_con = lock.newCondition();public  void set(String name)throws InterruptedException{lock.lock();try{while(flag)condition_pro.await();//t1,t2this.name = name+"--"+count++;System.out.println(Thread.currentThread().getName()+"...生产者.."+this.name);flag = true;condition_con.signal();}finally{lock.unlock();//释放锁的动作一定要执行。
        }}//  t3   t4  public  void out()throws InterruptedException{lock.lock();try{while(!flag)condition_con.await();System.out.println(Thread.currentThread().getName()+"...消费者........."+this.name);flag = false;condition_pro.signal();}finally{lock.unlock();}}
}class Producer implements Runnable
{private Resource res;Producer(Resource res){this.res = res;}public void run(){while(true){try{res.set("+商品+");}catch (InterruptedException e){}}}
}class Consumer implements Runnable
{private Resource res;Consumer(Resource res){this.res = res;}public void run(){while(true){try{res.out();}catch (InterruptedException e){}}}
}

===============================================================================

interrupt() 将处于强制冻结状态的线程,恢复到运行状态并处理InterruptedException

public class InterruptDemo {public static void main(String[] args) {Thread t = new Thread(new Demo());t.start();System.out.println("Start");t.interrupt();}
}class Demo implements Runnable{private boolean flag  = true;@Overridepublic synchronized void run() {while(flag){try {wait();} catch (InterruptedException e) {System.out.println("interrupted");flag = false;//通过修改标志位,让线程停止
            }}System.out.println("end");}
}

======================================================= 

守护线程: t1.setDaemon(true);

t1.start();

将线程声明为守护线程。(当前台线程停止时,守护线程强行停止)



join:

当A线程执行到了B线程的.join()方法时,A就会等待。等B线程都执行完,A才会执行。

join可以用来临时加入线程执行。

class Demo2 implements Runnable
{public void run(){for(int x=0; x<70; x++){System.out.println(Thread.currentThread().toString()+"....."+x);Thread.yield();}}
}public class JoinDemo
{public static void main(String[] args) throws Exception{Demo2 d = new Demo2();Thread t1 = new Thread(d);t1.start();t1.join();for(int x=0; x<40; x++){System.out.println("main....."+x);}System.out.println("over");}
}

优先级:setPriority(Thread.MAX_PRIORITY);//设置到最高优先级

线程组:每个线程属于其创建者所在的线程组。调用线程的toString方法可以看到其线程组。

 

转载于:https://www.cnblogs.com/grjelf/archive/2012/10/19/2726502.html

更多相关:

  • 多线程有什么好处?提高CPU的利用率,更好地利用系统资源,使用Monitor类可以同步静态/实例化的方法的全部代码或者部分代码段,使用不同的同步类创建自己的同步机制。多线程指从软件或者硬件上实现多个线程并发执行的技术。具有多线程能力的计算机因有硬件支持而能够在同一时间执行多于一个线程提升整体处理性能。多线程是指程序中包含多个执行流,即...

  • Step1:在界面主函数的构造函数中初始化多线程 auto mythread = new QThread(); //新建connect(mythread , &QThread::finished, mythread, &QObject::deleteLater);//线程运行结束后释放内存object1->moveToThread...

  • 一、thread的基本用法 参见C++使用thread类多线程编程 。 二、类外使用多线程,访问类的成员 这几种方式,新建线程都是在类外,然后通过把友元函数或者成员函数作为thread参数。 #include #include #include using namesp...

  • 本博文是根据中科大信息学院谭立湘老师的课件加上自己的理解整理出来的 ************************************************************************************ NVIDIA在2007年推出CUDA这个统一计算架构 CUDA的基本思想是支持大量的线程级并...

  • 一、parallel communication patterns   并行通信模式 Map:映射,在特定的位置读取和写入。 Gather:收集,从多个不同的位置读入,写入一个位置。 Scatter:分发,写入多个位置。 Transpose转置 结构数组缩写为AOS,数组结构缩写为SOA 转置运算是指任务重新排序内存中的数...

  • 来源:公众号|计算机视觉工坊(系投稿)作者:仲夏夜之星「3D视觉工坊」技术交流群已经成立,目前大约有12000人,方向主要涉及3D视觉、CV&深度学习、SLAM、三维重建、点云后处理、自动驾驶、CV入门、三维测量、VR/AR、3D人脸识别、医疗影像、缺陷检测、行人重识别、目标跟踪、视觉产品落地、视觉竞赛、车牌识别、硬件选型、学术交流、...

  • 点云PCL免费知识星球,点云论文速读。文章:Real-Time LIDAR-Based Urban Road and Sidewalk Detection for Autonomous Vehicles作者:Ern˝o Horváth  , Claudiu Pozna ,and Miklós Unger编译:点云PCL代码:http...

  • 文章:Semantic Histogram Based Graph Matching for Real-Time Multi-Robot Global Localization in Large Scale Environment作者:Xiyue Guo, Junjie Hu, Junfeng Chen, Fuqin Deng, T...

  • 点云PCL免费知识星球,点云论文速读。文章:Robust Place Recognition using an Imaging Lidar作者:Tixiao Shan, Brendan Englot, Fabio Duarte, Carlo Ratti, and Daniela Rus编译:点云PCL(ICRA 2021)开源代码:...

  • 文章:A Survey of Calibration Methods for Optical See-Through Head-Mounted Displays作者:Jens Grubert , Yuta Itoh, Kenneth Moser编译:点云PCL本文仅做学术分享,如有侵权,请联系删除。欢迎各位加入免费知识星球,获取PD...