多线程基本知识点
写的不好请多多指教哈
一 首先我们要知道什么是多线程:
多线程是实现后台服务程序 可以同时处理多个线程完成任务 ,并且不会发生阻塞现象,以提高系统的效率。
二 使用多线程的优点:
1):程序的运行速度可能加快
2):可以分别设置各个任务的优先级以优化性能
3):可以随时停止任务等;
三 使用多线程的缺点:
1):等候使用共享资源的时候会造成程序的运行速度变慢;
2):线程的死锁。
3):当多个线程需要对公有变量进行写操作时,后面的一个线程会修改前一个线程存放的数据,从而使前一个线程的参数被修改等
四 如何使用线程:
1):在控制台中输出的main就是一个名叫做main的线程在执行main方法中的代码 ,控制台中的main与main方法是没有任何关系的
2):线程的随机性
public class Thead extends Thread{
public static void main(String[] args) {
Thead thead1 = new Thead();
thead1.setName("main");
thead1.start();
Thead thead2 = new Thead();
thead2.start();
}
//重写run方法
@Override
public void run() {
// TODO Auto-generated method stub
try {
for (int i =1; i <=3; i++) {
int t = (int)(Math.random()*1000);
Thread.sleep(t);
System.out.println("当前线程名:"+Thread.currentThread().getName());
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
在此我们可以发现每次CPU执行某个线程都具有不确定性。(谁先抢到谁先执行)
五 Thread类中的start()和run()方法有什么区别:
1):start方法表示该线程有资格去抢cpu资源,但没有执行
2):run方法表示该线程抢到cpu资源后执行run代码块里面得方法
线程通常都有5种状态:创建、就绪、运行、阻塞和死亡。
1):创建状态:在生成线程对象,没有调用该对象的start()方法之前,这时线程处于创建状态。
2):就绪状态:当调用了线程对象的start方法之后,该线程就进入就绪状态,但此时线程调度程序还没有把该线程设置为当前线程,此时处于就绪状态。在线程运行之后,从等待或睡眠中回来之后,也会处于就绪状态。
3):运行状态:线程调度程序将处于就绪状态的线程设置为当前线程,此时线程就进入运行状态,开始运行run函数当中的代码。
4):阻塞状态:线程正在运行的时候,被暂停之后再继续运行。sleep(休眠)、suspend(线程被挂起)、wait(等待)等方法都可以导致线程阻塞。
5):死亡状态:如果一个线程的run方法 执行结束或者调用stop方法后,该线程就会死亡。对于已经死亡的线程,无法再使用start方法令其进入就绪。
六 线程的状态图展示:
七 线程通信的实列 和 wait notify机制以及synchronized线程安全
定义一个产品类
/**
* 产品实体类
* @author Administrator
*
*/
public class Product {
private int pid;
private String pname;
public int getPid() {
return pid;
}
public void setPid(int pid) {
this.pid = pid;
}
public String getPname() {
return pname;
}
public void setPname(String pname) {
this.pname = pname;
}
}
定义一个工厂类
/**
* 工厂类
* @author Administrator
*
*/
public class Factory {
private Vector<Product> vs=new Vector<Product>();
//生产产品
public synchronized void addPro(Product p){
if(vs.size()>99){
try {
this.wait(); //等待
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else{
this.notifyAll(); //唤醒所有线程
vs.add(p); //增加商品
System.out.println(Thread.currentThread().getName()+"生产了第"+vs.size()+"个产品");
}
}
//销售产品
public synchronized void sale(){
if(vs.size()<=0){
try {
this.wait(); //等待
} catch (Exception e) {
// TODO: handle exception
}
}else{
this.notifyAll(); //唤醒所有线程
vs.remove(0); //
System.out.println(Thread.currentThread().getName()+"销售了第"+vs.size()+"个产品");
}
}
}
定义一个制造者
/**
* 制造者类
* @author Administrator
*
*/
public class Maker implements Runnable{
private Factory factory;
public Maker(Factory f){
this.factory=f;
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
factory.addPro(new Product());
}
}
}
定义一个销售者实体类
/**
* 销售者实体类
* @author Administrator
*
*/
public class Saler implements Runnable{
private Factory factory;
public Saler(Factory f){
this.factory=f;
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
factory.sale();
}
}
}
结论:
多个线程在处理同一个资源,并且任务不同时,需要线程通信来帮助解决线程之间对同一个变量的使用或操作。
就是多个线程在操作同一份数据时, 避免对同一共享变量的争夺。