java线程基础学习

本文详细介绍了线程的基本概念,包括程序、进程与线程的关系,以及如何通过继承Thread类或实现Runnable接口来创建线程。此外,还探讨了线程的生命周期,同步锁与同步方法的使用,以及线程通信机制,如wait()、notify()和notifyAll()的运用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

线程的创建和使用

一、基本概念
程序 - 进程 - 线程
程序:是为完成特定任务、用某种语言编写的一组指令的集合。
进程:是程序的一次执行过程,或是正在运行的一个程序
线程:进程可进一步细化为线程,是一个程序内部的一条执行路径

二、创建或使用线程
1)继承Thread类
创建线程的语法:

  • 1)继承一个线程类;public class TortThread extends Thread
  • 2)重写run()方法;
  • 3)run()就是线程要执行的代码;
  • 4)当run()方法执行完了,线程就结束了。

//创建兔子线程:
public class HareThread extends Thread {

       @Override
       public void run() {

               // 兔子跑步的一个行为;
               int hareStep = 0;

               while (hareStep <5) {

                       hareStep += 2;
                       System.out.println("兔子跑了" + hareStep + "步");

               }

       }

}



//创建乌龟线程:
public class TortThread extends Thread {

       @Override
       public void run() {
               
               //乌龟跑步的一个行为;
               int tortStep=0;
               
               while(tortStep<5){
                       
                       tortStep+=1;
                       System.out.println("乌龟跑了"+tortStep+"步");
                       
               }
               
       }
       
}



//测试类
public class Test {

       public static void main(String[] args) {
               
               for(int i=0;i<5;i++){
                       System.out.println("主线程开始:");
                       
               }
               
               TortThread tt=new TortThread();//创建线程对象
               HareThread ht=new HareThread();//创建线程对象
               
               tt.start();//启动线程;
               ht.start();//启动线程;
               
               for(int i=0;i<5;i++){
                       System.out.println("主线程结束:");
                       
               }

       }

}


2)实现Runnable接口

创建线程的语法:

  • 1)实现Runnable接口;public class HareRunnable implements Runnable
  • 2)实现Runnable的run()方法;
  • 3)run()就是线程要执行的代码;
  • 4)当run()方法执行完了,线程就结束了。
  • 5)先创建Runnable对象:TortRunnable tr=new TortRunnable();
  • 再创建线程对象:Thread tt=new Thread(tr);
    
  • Runnable不是线程对象,而是线程的一个参数;
    
  • 启动时要启动线程,不要启动Runnable:tt.start();
    
public class TortRunnable implements Runnable {

       @Override
       public void run() {
               //乌龟跑步的一个行为;
                               int tortStep=0;
                               
                               while(tortStep<5){
                                       
                                       tortStep+=1;
                                       System.out.println("乌龟跑了"+tortStep+"步");
                                       
               }
       }

}




public class HareRunnable implements Runnable {

                       @Override
                       public void run() {
                               // 兔子跑步的一个行为;
                               int hareStep = 0;

                               while (hareStep <5) {

                                       hareStep += 2;
                                       System.out.println("兔子跑了" + hareStep + "步");

                               }
                               
                       }

}



public class Test {

       public static void main(String[] args) {
               
               TortRunnable tr=new TortRunnable();
               Thread tt=new Thread(tr);
               
               HareRunnable hr=new HareRunnable();
               Thread ht=new Thread(hr);
               
               tt.start();
               ht.start();

       }

}


3)常用方法
currentThread() 返回对当前正在执行的线程对象的引用。
getName() 返回此线程的名称。
setName(String name) 当前线程赋值线程名称
getPriority() 返回此线程的优先级。
setPriority(int newPriority) 设置线程的优先级。(1~10)由低到高,默认的优先级5
isAlive() 测试这个线程是否活着。
join() 参加 当前线程A中调用了B线程的join();A线程让出CPU资源给B线程,直到B线程结束
再去执行A线程的剩余内容
run() 启动线程调用的方法
sleep(long millis) 线程休眠 millis 毫秒
start() 导致此线程开始执行; Java虚拟机调用此线程的run方法。
yield() 当前线程会让出CPU资源(大公无私)。
三、继承方式和实现方式的联系与区别
两种方法的优劣势:
继承Thread类:就不能继承其他类了;但思路简单;
实现Runnable接口:还可以继承其他类;但设计复杂;实现多个线程访问同一资源的设计;
1)避免了单继承的局限性
2)多个线程可以共享同一个接口实现类的对象的资源,非常适合多个相同线程来处理同一份资源。
类似于示例中的:ticket共享资源
四、线程的生命周期(五个状态)Thread.state
新建 就绪 运行 ( 阻塞) 死亡
线程执行过程和生命周期:
1)新生状态:TortThread tt=new TortThread();
2)就绪状态:tt.start();
3)就绪状态《----》运行状态之间切换。
4)终止:当run()方法执行完了,线程就终止了。
/*
*1.sleep():Thread.sleep():哪个线程调用,哪个线程sleep();

  • 线程进入阻塞状态:不抢占CPU了,释放CPU;
  • 阻塞解除:进入就绪状态;

*2.yield():Thread.yield():哪个线程调用,哪个线程yield();

  • 线程暂停执行;进入就绪状态;

*3.join():tt.join(),"tt"这个线程先执行完,在此期间"tt.join()"之后的主线程的代码就不执行了(主线程进入阻塞状态);

  • 等tt执行完之后,主线程解除阻塞。
    */
    注意:启动线程:tt.start();不要直接调用run()方法。
public class Test {

       public static void main(String[] args) {

               for (int i = 0; i < 5; i++) {
                       System.out.println("主线程开始:");

               }

               TortThread tt = new TortThread();
               HareThread ht = new HareThread();

               tt.start();
               ht.start();
               
               
           try {
                       Thread.sleep();
               } catch (InterruptedException e) {
                       // TODO Auto-generated catch block
                       e.printStackTrace();
               }
               

               
               for (int i = 0; i < 5; i++) {
                       System.out.println("主线程结束:");

               }  

       }

}


//乌龟线程和兔子线程
public class HareThread extends Thread {

       @Override
       public void run() {

               // 兔子跑步的一个行为;
               int hareStep = 0;

               while (hareStep < 5) {

                       hareStep += 2;
                       System.out.println("兔子跑了" + hareStep + "步");

               }

       }

}


public class TortThread extends Thread {

       @Override
       public void run() {

               // 乌龟跑步的一个行为;
               int tortStep = 0;

               while (tortStep < 5) {

                       tortStep += 1;
                       System.out.println("乌龟跑了" + tortStep + "步");

               }

       }

}



五、同步锁同步方法
1.java中每一个对象都有自己的一把对象锁。
2.同步锁即同一对象的锁,也叫同步监视器。特点如下:
同步监视器
synchronized (obj){ }中的obj称为同步监视器
同步代码块中同步监视器可以是任何对象,但是推荐使用共享资源作为同步监视器
同步方法中无需指定同步监视器,因为同步方法的同步监视器是this,也就是该对象本事
优点:解决了线程安全问题
缺点:性能下降;会带来死锁

线程同步:synchronized关键字
*1.同步方法:public synchronized void changeBalance();

/*
*功能:4个窗口卖200张票(把同步代码块转成同步方法)
*
*分析:1.4个窗口是4个线程对象;
*    2.4个窗口卖票的行为是一样的,一个线程类即可;
*    3.4个窗口要访问的同一资源是:200张票;
*    4.200张票:设计实现Runnable接口;
*    
*
*
*/

//设计票务资源;
public class TicketRunnable implements Runnable {

       private int ticketNum = 20;// 四个窗口卖的总票数;
       
       Object lock=new Object();

       @Override
       public void run() {

                       while (true) {
                               
                               boolean flag=sellOne();//接收同步方法的返回值;
                               
                               if(!flag){//判断返回值,确定是否结束循环。
                                       break;
                               }
                               
                               
                               try {
                                       Thread.sleep(5);
                               } catch (InterruptedException e) {
                                       // TODO Auto-generated catch block
                                       e.printStackTrace();
                               }
                       }
                       
               }
       
       //定义同步方法;
       public synchronized boolean sellOne(){
               
                       
                       if(ticketNum==0){
                               return false;
                       }
                       
                       System.out.println(Thread.currentThread().getName() + ":卖出了第" + ticketNum + "张票");
                       ticketNum--;
                       return true;
               }
       }


//测试类
public class Test {

       public static void main(String[] args) {
               
               //创建票务资源;
               TicketRunnable tr=new TicketRunnable();
               
               //创建四个窗口;
               Thread th1=new Thread(tr,"1号窗口");
               Thread th2=new Thread(tr,"2号窗口");
               Thread th3=new Thread(tr,"3号窗口");
               Thread th4=new Thread(tr,"4号窗口");
               
               th1.start();
               th2.start();
               th3.start();
               th4.start();

       }

}





     

*2.同步代码块:synchronized(this){需要同步的代码}

  •      this:同步锁,线程得到同步锁才能执行同步代码块;执行完了,释放锁,其他线程可以获取该锁。
    
//设计票务资源;
public class TicketRunnable implements Runnable {

       private int ticketNum = 20;// 四个窗口卖的总票数;
       
       Object lock=new Object();

       @Override
       public void run() {

                       while (true) {
                               
                               synchronized(this){
                                       
                                       if(ticketNum==0){
                                               break;
                                       }
                                       
                                       System.out.println(Thread.currentThread().getName() + ":卖出了第" + ticketNum + "张票");
                                       ticketNum--;
                               }
                               
                               try {
                                       Thread.sleep(5);
                               } catch (InterruptedException e) {
                                       // TODO Auto-generated catch block
                                       e.printStackTrace();
                               }
                       }
                       
               }
       }


//测试类

public class Test {

       public static void main(String[] args) {
               
               //创建票务资源;
               TicketRunnable tr=new TicketRunnable();
               
               //创建四个窗口;
               Thread th1=new Thread(tr,"1号窗口");
               Thread th2=new Thread(tr,"2号窗口");
               Thread th3=new Thread(tr,"3号窗口");
               Thread th4=new Thread(tr,"4号窗口");
               
               th1.start();
               th2.start();
               th3.start();
               th4.start();

       }

}







六、线程通信
wait() 与 notify() 和 notifyAll()
/*
*功能:生产者和消费者
*
*wait();释放锁,进入阻塞状态;
*notify();只唤醒一个等待本对象锁的线程;
*notifyAll();唤醒全部等待本对象锁的线程;
*
*
*/

public class ProduceThread extends Thread {

       private SteamStack ss;

       public ProduceThread() {
               // TODO Auto-generated constructor stub
       }

       public ProduceThread(SteamStack ss) {
               super();
               this.ss = ss;
       }

       public void run() {

       
               int i = 1;
               while (i <= 10) {

                       synchronized (ss) {

                               // 1.判断SteamStack有没有产品;
                               // 2.如果没有,就生产;如果有,就不生产,放掉锁,进入阻塞状态;
                               while (ss.hasProduct) {

                                       try {
                                               ss.wait();// 释放锁;线程进入阻塞状态;
                                       } catch (InterruptedException e) {
                                               // TODO Auto-generated catch block
                                               e.printStackTrace();
                                       }
                               }

                               // 生产;
                               System.out.println("生产第" + i + "个馒头");
                               i++;
                               ss.hasProduct = true;// 把状态设成true;
                               ss.notify();// 把现在正在等待对象锁的线程唤醒;

                       }
               }
       }

}


public class ProduceThread extends Thread {

       private SteamStack ss;

       public ProduceThread() {
               // TODO Auto-generated constructor stub
       }

       public ProduceThread(SteamStack ss) {
               super();
               this.ss = ss;
       }

       public void run() {

       
               int i = 1;
               while (i <= 10) {

                       synchronized (ss) {

                               // 1.判断SteamStack有没有产品;
                               // 2.如果没有,就生产;如果有,就不生产,放掉锁,进入阻塞状态;
                               while (ss.hasProduct) {

                                       try {
                                               ss.wait();// 释放锁;线程进入阻塞状态;
                                       } catch (InterruptedException e) {
                                               // TODO Auto-generated catch block
                                               e.printStackTrace();
                                       }
                               }

                               // 生产;
                               System.out.println("生产第" + i + "个馒头");
                               i++;
                               ss.hasProduct = true;// 把状态设成true;
                               ss.notify();// 把现在正在等待对象锁的线程唤醒;

                       }
               }
       }

}


public class SteamStack {

       boolean hasProduct=false;//初始值是false,表示没有产品;
}

public class Test {

       public static void main(String[] args) {
       
          //馒头筐;
          SteamStack ss=new SteamStack();
         
          //生产线程和消费线程;
          ProduceThread pt=new ProduceThread(ss);
          ConsumeThread ct=new ConsumeThread(ss);
         
          pt.start();
          ct.start();

       }

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值