Java 多线程

进程是一个程序的一次执行过程,是动态的。

线程是进程的一个执行路径,当进程需要执行多项任务,就需要多线程。

Java程序的线程至少有main线程和垃圾回收线程。

多线程的创建:

一 . 继承java.lang.Thread(这样就不能继承其他的类,单继承),重写run(),方法体就是线程执行的任务。

      创建该类对象,调用start()启动该线程并调用相应的run()。

     class TestThread{
    public static void main(String[] args){
         SubThread st1 = new SubThread();     
         st1.start();        
    }
}

class SubThread extends Thread{

      static   int ticket =100;

      static Object obj =new Object();  //同步监视器

 

public void run(){

 

while(true){ 

                    synchronized(obj){

                       if(ticket > 0){
                            System.out.println(Thread.currentThread().getName()+": "+ ticket--);
                        }else{
                             break;

                         }                   

                  }

}
}
}

       注意: 如果直接使用对象调用run(),那就不是多线程,只是普通地调用成员方法,仍然是主线程在执行。

       Thread常用方法: start()  //启动线程并调用run()

                                   run()// 被重写,包含线程执行的任务体

                                   currentThread()// 静态方法,调取当前的线程

                                   getName()// 获取线程名字

                                    setName(String)// 设置线程的名字

                                     boolean isAlive()//判断线程是否仍然存活

                                     sleep(long )//显式地让线程睡眠一段时间

                                     yield()//  释放CPU的执行权

                                      join()//在A线程中调用B线程的join(),表示执行到此方法时,强制停止A线程,

                                                 调用B线程直至B线程执行完毕。                                                                         

二. 实现Runnable接口

     1.创建一个实现java.lang.Runnable接口的类,实现run()方法;

     2.创建一个该类对象,并将其作为Thread构造器的形参,创建线程对象

  实际上Thread类也是实现的Runnable接口,显然实现接口的方式要优于继承的方式,

第一,实现的方式避免了java单继承的局限性;

第二,如果多个线程需要操作同一份资源,更适合使用实现的方式。

import java.lang.Runnable;
import java.lang.Thread;
class TestRunnable{
public static void main(String[] args){
threadRun thr = new threadRun();
      Thread t1 = new Thread(thr);
//两个线程对象共享的是同一个对象thr,thr.ticket也是一样共享
      t1.start();
      Thread t2 = new Thread(thr);//两个线程对象共享的是同一个对象
      t2.start();
}
}
class threadRun implements Runnable{

int ticket=100;

        Object obj = new Object();

 

    public void run(){

 

       while(true){

           synchronized(obj){

                   if(ticket > 0){
                            System.out.println(Thread.currentThread().getName()+": "+ ticket--);
                        }else{
                             break;

                         }          

             }

      }

 

  }
}

 

使用多线程的优点:

1.提高应用程序的响应,增强用户体验。

2.提高CPU的利用率。

3.改善程序结构,将既长又复杂的进程分为多个线程独立运行,利于理解和修改。

Java中线程分为: 守护线程和用户线程。

线程的生命周期: 新建(线程对象被创建),

                        就绪(start(),进入线程队列等待CPU时间片),

                         运行(就绪的线程得到CPU执行权,run()),

                         阻塞(被人为挂起或者执行输入输出操作,让出CPU并临时终止自己的执行),

                         死亡(线程完成全部工作或线程被强制性终止)

新建-----start()--->就绪<----获得执行权(失去执行权)----->运行-------正常执行完/出现异常未处理----->死亡

运行---sleep()   / 等待同步锁     /wait()     /   join()   /     suspend()---> 阻塞

阻塞---时间到/获取同步锁/notify()notifyAll()/join执行完/resume()----> 就绪

线程安全问题:

 由于一个线程在操作共享数据过程中,未执行完毕的情况下,另外的线程参与进来,导致共享数据存在安全问题。

线程的同步机制:

方式一: 同步代码块   synchronized(对象){//需要被同步的代码},该对象充当共享监视器,要保证只有一个线程可以获取该监视器

                                      对于一般方法内,使用同步代码块,可以考虑使用this,对于静态方法使用当前类(类名.class)充当监视器

方式二:同步方法    将操作共享数据的方法声明为synchronized,非静态同步方法的锁就是当前对象(只适用于实现接口方式),

                                      静态同步方法的锁为当前类本身(类名.class)

方式三:同步锁(JDK5.0以后增加)

当前线程的同步方法,同步代码块执行结束,或者遇到break,return结束,以及异常未处理,都会释放锁。

当前线程wait()也释放锁,但是yield(),sleep()不会释放锁。

死锁示例: 两个线程分别持有对方需要的锁,都不释放,只能一直等待

public static void main(String[] args){
     StringBuffer sb1 = new StringBuffer();
      StringBuffer sb2 = new StringBuffer();
      new Thread(){
      public void run(){
       synchronized(sb1){
      try{// 让线程sleep()是为了让问题更明显
      Thread.currentThread().sleep(10);
      }catch(InterruptedException e){
                    e.printStackTrace();
      }

      sb1.append("A");
      synchronized(sb2){
                    sb2.append("B");
                    System.out.println("sb1: "+ sb1+ " sb2: "+sb2);
      }
      }
      }
      }.start();
      new Thread(){
      public void run(){
      synchronized(sb2){
      try{// 让线程sleep()是为了让问题更明显
      Thread.currentThread().sleep(10);
      }catch(InterruptedException e){
                    e.printStackTrace();
      }

                sb1.append("C");
                synchronized(sb1){
                   sb2.append("D");
                   System.out.println("sb1: "+ sb1+ " sb2: "+sb2);
                }
      }
      }
      }.start();
  }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
该资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。
该资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值