java学习第23天--线程

线程的概述
进程: 计算机中特定功能的程序在数据集上的一次运行
线程: 计算机进程的一个单元
多线程: 一个进程有多个线程在同时运行
jvm: jvm是多线程的,在我们运行jvm的时候后台会运行垃圾回收的线程,来清理没有被引用的对象

进程与线程的区别:
进程之间互相隔离,不共享数据
同一个进程的线程之间可以共享数据

线程的实现
创建新执行线程有两种方法
一种方法是将类声明为Thread的子类.该子类应重写Thread类的run方法.接下来可以分配并启动该子类的实例.
线程启动的时候使用线程的start方法而不是run

继承Thread类
1.子类重写父类中的run方法,将线程运行的代码存放在run中,即:线程体
2.建立子类对象的同时线程也被创建
3.通过调用start方法开启线程

class MyThread extends Thread{
  public void run(){
  // 业务逻辑 , 线程体  
  }
}
public class ThreadDemo{
  public static void main(String[] args){
  new MyThread().start();
  new MyThread().start();
  }
}

另一种方法是声明实现Runnable接口的类.该类然后实现run方法,然后可以分配该类的实例,在创建Thread时作为一个参数来传递并启动.
实现 Runnable 接口
1. 自定义类实现接口中的 run 方法。
2. 通过 Thread 类创建线程,并将实现了 Runnable 接口的子类对象作为参数传递给 Thread 类的构造方法
3.Thread 类对象调用 start 方法开启线程
class MyThread implements Runnable{
  public void run(){
  // 业务逻辑 , 线程体
  }
}
pulbic class ThreadDemo{
  public static void main(String[] args){
  MyThread t1 = new MyThread();
  new Thread(t1).start();
  new Thread(t1).start();
  }
}

线程基本常用操作
获取线程名字: getName()
获取main方法所在线程名字:Thread.currentThread().getName()
设置线程名字: 对象.setname()
设置优先级: 对象.setPriority()
线程的加入: 对象.join() //执行完之后,再执行其他进程
线程的谦让: Thread.yield()
线程的控制: 对象.setDaemon(boolean on)
线程的终止: 对象.stop() //已过时
对象.interrupt() //推荐使用


线程执行原理
线程的并发执行是通过多个线程不断的切换CPU的资源,这个速度是非常快的,我们感觉不到,我们能感知到的是多个线程在并发的执行.

线程的生命周期
新建: 线程被 new出来
准备就绪: 线程具有执行的资格,即线程调用了 start(),没有执行的权利
运行: 具备执行的资格和具备执行的权利
阻塞: 没有执行的资格和执行权利
销毁: 线程的对象变成了垃圾,释放资源

并发
互联网的项目中存在着大量的并发的案例,如卖火车票,电商网站.
范例:火车找有100张票,4个窗口同时买票
分析: 4个窗口是4个线程同时在运行,100张票是4个线程的共享资源
采用继承Thread来实现,针对线程的安全问题,我们需要使用同步(就是要加锁,共享资源智能一个人同时访问)锁.
语法:
synchronized(锁对象){
//操作共享资源的代码
}
同步代码加在什么地方?
1.代码被多个线程访问
2.代码中有共享的数据
3.共享数据被多条语句操作
package com.czz.test01;
 
public class SaleTicket extends Thread{
   private String name ;
  
   public SaleTicket(String name ) {
      super ( name );
   }
 
   // 加上 static, 表明 100 张票是共享的数据
   private static int tickets = 100;
  
   // 同步锁对象
   private static Object obj = new Object ();
  
   @Override
   public void run() {
      while ( true ) {
         // 同步代码块
         synchronized ( obj ) {
            if ( tickets > 0) {
                System. out .println( this .getName() + " 正在卖第 " + tickets -- + " 张票 " );
            } else {
                System. out .println( " 票已售罄 " );
                break ;
            }
         }
      }
   }
}
 测试对象
package com.czz.test01;
 
public class TicketTest {
   public static void main(String[] args ) {
      SaleTicket st1 = new SaleTicket( " 窗口 1" );
      SaleTicket st2 = new SaleTicket( " 窗口 2" );
      SaleTicket st3 = new SaleTicket( " 窗口 3" );
      SaleTicket st4 = new SaleTicket( " 窗口 4" );
 
      st1 .start();
      st2 .start();
      st3 .start();
      st4 .start();
   }
}
 































猜你喜欢

转载自blog.csdn.net/czz1141979570/article/details/80170929
今日推荐