ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

多线程

2021-12-16 09:32:07  阅读:165  来源: 互联网

标签:run Thread MyThread 线程 new 多线程 public


1 多线程

1.1 进程和线程

进程:是正在运行的程序

是系统进行资源分配和调用的独立单位

每一个进程都有它自己的内存空间和系统资源

线程:是进程中的单个顺序控制流,是一条执行路径

单线程:一个进程如果只有一条执行路径,则称为单线程程序多线程:一个进程如果有多条执行路径,则称为多线程程序

1.2 多线程的实现方式

方法一:

1)定义一个MyThread类继承Thread类

(2)在MyTread类中重写run方法

(3)创建MyThread类对象

(4)调用start方法启动线程

说明:

为什么要重写run方法:

因为run是用来封装被线程执行的代码

run和start方法的区别

run封装线程执行的代码,直接调用,相当于普通方法调用

start启动线程然后由JVM调用此线程的run方法

代码演示:

public class MyThread extends Thread{

  @override

public void run(){

}

}

public ………main(){

 

MyThread mt1=new MyThread();

MyThread mt2=new MyThread();

mt1.run();

mt1.start();

mt2.start();

}

 

1.3设置和获取线程名称

方法介绍

void setName(String name)将此线程的名称更改为等于参数name

String getName()返回此线程的名称

Thread currentThread()返回对当前正在执行的线程对象的引用

代码演示      

 

public class MyThread extends Thread {  

  public MyThread() {}    

public MyThread(String name) {        super(name);   }   

 @Override  

 public void run() {        System.out.println(getName();}

public class MyThreadDemo {    

public static void main(String[] args) {    

   MyThread my1 = new MyThread();      

  MyThread my2 = new MyThread();   

   my1.setName("高铁");        

my2.setName("飞机");         

   MyThread my1 = new MyThread("高铁");      

 MyThread my2 = new MyThread("飞机");

     System.out.println(Thread.currentThread().getName());

}}

1.4线程优先级

1.4.1线程调度

(1)两种调度方式:

分时调度模型:所有线程轮流使用 CPU 的使用权,平均分配每个线程占用 CPU 的时间片.

抢占式调度模型:优先让优先级高的线程使用 CPU,如果线程的优先级相同,那么会随机选择一个,优先级高的线程获取的 CPU 时间片相对多一些

(2)Java使用的是抢占式调度模型

(3)随机性:

假如计算机只有一个 CPU,那么 CPU 在某一个时刻只能执行一条指令,线程只有得到CPU时间片,也就是使用权,才可以执行指令。所以说多线程程序的执行是有随机性,因为谁抢到CPU的使用权是不一定的

1.4.2 线程优先级相关方法

final int getPriority() 返回此线程的优先级

final void setPriority(int newPriority)更改此线程的优先级,默认5,线程范围 1-10。

 

 

1.5线程控制

 相关方法

sleep(long millis):使当前线程(即调用该方法的线程)暂停执行一段时间,让其他线程有机会继续执行,但它并不释放对象锁

wait():使当前线程暂停执行并释放对象锁标志

notify()唤醒等待的线程

 join(): 直观解释就是”等待调用此方法的线程死去,再执行其他线程“。说得更直观一点就是:在线程 t1 内部调用t2.join(), 那么 t1 将会等待 t2 执行完毕后才会继续执行

 

Wait和sleep方法不同点 : 
1.每个对象都有一个锁来控制同步访问。Synchronized关键字可以和对象的锁交互,来实现线程的同步。  
sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。  
2.wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用  
3.sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常 

4.sleep是线程类(Thread)的方法,导致此线程暂停执行指定时间,给执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复。调用sleep不会释放对象锁。

5.wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。

 

join方法的作用,代码演示

先写一个子线程

public class MyThread extends Thread{

     public MyThread(String name){

         super(name);

    }

    

    @Override

    public void run(){

        for(int i=1;i<=2;i++){

            System.out.println(this.getName() + ":" + i);

        }

    }

}

 

 

 再写主线程测试类

public class TestThread {

     public static void main(String[] args) throws InterruptedException

            MyThread mt = new MyThread("子线程");

        mt.start();

        for (int i = 1; i <= 2; i++) {

        System.out.println("主线程:" + i);

     }

     }

 

}

 

 

 执行main方法,打印结果很明显,主线程和子线程会交替打印

主线程:1

子线程:1

主线程:2

子线程:2

 

 

 然后,我们在主线程打印之前,加一句mt.join(),会怎样呢?

public static void main(String[] args) throws InterruptedException {

           

            MyThread mt = new MyThread("子线程");

        mt.start();

       

        mt.join();

       

        for (int i = 0; i <= 2; i++) {

        System.out.println("主线程:" + i);

            }

     }

 

 执行main方法,打印结果如下:

子线程:1

子线程:2

主线程:1

主线程:2

————————————————

结论:原来主线程和子线程是并行的关系,但是一旦使用了join()方法,就会变成串行的关系;当主线程调用子线程的join()方法时,意味着必须等子线程执行完毕之后,主线程才会开始执行。

 

 

1.6实现多线程方式二:实现Runnable接口

1.6.1 实现步骤

(1)定义一个类MyRunnable实现Runnable接口

(2)在MyRunnable类中重写run()方法

(3)创建MyRunnable类的对象创建Thread类的对象,把MyRunnable对象作为构造方法的参数

(4)启动线程

1.6.2代码演示:

public class MyRunnable implements Runnable {  

 @Override    

public void run() {            

System.out.println(Thread.currentThread().getName());       }}

public class MyRunnableDemo {  

  public static void main(String[] args) {    

    //创建MyRunnable类的对象        

MyRunnable my = new MyRunnable();       

  //创建Thread类的对象,把MyRunnable对象作为构造方法的参数  

       Thread t1 = new Thread(my);//    

  Thread t2 = new Thread(my);    

//Thread(Runnable target, String name)    

   Thread t1 = new Thread(my,"高铁");        

Thread t2 = new Thread(my,"飞机");         

//启动线程        

t1.start();        t2.start();

}}

 

1.6.3   多线程的实现方案有两种:

继承Thread类;

实现Runnable接口.

相比继承Thread类,实现Runnable接口的好处:

避免了Java单继承的局限性适合多个相同程序的代码去处理同一个资源的情况,把线程和程序的代码、数据有效分离,较好的体现了面向对象的设计思想

 

 

1.7 线程的生命周期

 

2 线程同步

2.1 Synchronized

卖票案例

某电影院目前正在上映国产大片,共有100张票,而它有3个窗口卖票。

public class SellTicket implements Runnable{

private int tickets=100;

//三个窗口共用一把锁

private Object obj=new Object();

@override

public void run(){

// 没票了,也一直有人问

     whiletrue{

// Synchronizednew Object

错误每个线程创建一把锁

synchronizedobj{

  iftickets>0{

       try{

        Thread.sleep(100);//出票时间

}catch()

   System…(Thread.current.getname()+”正在卖第”+tickets+”张票”);

tickets--

}}}}

  Public ….main(){

   SellTicket st=new SellTicket();

Thread t1=new Thread();

Thread t2=new Thread();

Thread t3=new Thread();

t1.start(); t2.start(); t3.start();

}

 

同步代码块格式:synchronized(任意对象):就相当于给代码加锁了,任意对象就可以看成是一把锁

同步的好处和弊端好处:解决了多线程的数据安全问题弊端:当线程很多时,因为每个线程都会去判断同步上的锁,这是很耗费资源的,无形中会降低程序的运行效率

同步方法:

格式:把synchronized加到方法上

修饰符staticsynchronized返回类型方法名

同步方法的锁对象是this

同步静态方法的锁对象是类名.class

线程安全的类:StringBuffer/Vector/Hashtable

线程不安全的类:StringBuilder/ArrayList/HashMapb

 

2.2 lock

lock锁提供了获取锁和释放锁的方法。

Lock锁提供了比使用synchronized方法可以获得更广泛的锁操作对象

代码演示:

public class SellTicket implements Runnable

{  private int tickets=100

private Lock lock=new ReenTrantLock();

@override

public void run(){

while(true){

try{

 lock.lock();

if(tickets>0){

try{Thread.sleep(100);}catch{}

   

System……(“ 正卖几张票”);

Tickets--;

}

}finally{lock.unlock();}

}

}

 

}

 

标签:run,Thread,MyThread,线程,new,多线程,public
来源: https://www.cnblogs.com/lyqjava/p/15696403.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有