• Java多线程详解


    线程(Thread)是指程序的运行流程,多线程机制指同时运行多个程序块。

    Java中实现多线程有两种方法:继承Thread类;实现Runnable接口。

    Thread类的run()方法的制定者:接口Runnable中的run();

    Thread类中没有完全实现Runnable接口中的run()方法。

    Thread类是Runnable接口的子类,Thread类中的run()方法调用的是Runnable接口中的run()方法。

    接口是由全局变量和公共抽象方法所组成的。

    所以,在Thread子类中,必须覆写Thread类中的run()方法。

    启动线程时,不能直接调用run()方法,而是调用从Thread类中继承而来的start()方法;

    即同一个对象只能调用一次start方法。

    如果一个类继承了Thread类,那么只能调用一次start()方法,如果多次调用,

    将会出现IllegalThreadStateException”异常。

    Runnable接口中只有一个方法:run();

    RunnableThread中的run方法和自定义的run方法之间的关系:

     1 interface Runnable{
     2     public abstract void run();
     3 }                                //remove method body
     4 
     5 public class Thread implements Runnable {
     6     private Runnable target;                //封装
     7     public Thread(Runnable target,String name){        //构造函数,name是线程的名称
     8         init(target);
     9     }
    10     
    11     private void init(Runnable target2) {    //检验关口,给属性赋值
    12         this.target = target;
    13     }
    14     
    15     public void run() {
    16         if(target != null){
    17             target.run();    //此run方法指的是自定义的run方法,即Runable中的run方法
    18                     //整个过程中,只有一个对象,只有这个对象有能力调用自定
    19                     //义的run方法。
    20         }    
    21     }    
    22 }
    23 class MyThread implements Runnable{
    24     public void run() {                        //自定义的run方法
    25         
    26     }
    27 }

    由于使用Runable的整个过程中,只产生一个对象,所以可以方便地实现资源的共享。

    这也是Runable优于Thread之处。

    Java程序每次运行至少启动两个线程:main线程、垃圾收集线程。

    Thread类中常用的方法:

    currentThread(静态),通过类名Thread直接调用;

    判断线程是否启动(存活)

     1 class MyThread implements Runnable{
     2     public void run(){
     3         for(int i=0;i<3;i++){
     4             System.out.println(Thread.currentThread().getName()+"运行………"+i);
     5         }
     6     }
     7 }
     8 
     9 public class ThreadAliveDemo {
    10 
    11     public static void main(String[] args) {
    12         MyThread mt = new MyThread();
    13         Thread t = new Thread(mt);   
    14         System.out.println("线程开始执行之前……"+t.isAlive());
    15         
    16         t.start();
    17         
    18         for(int i=0;i<5;i++){
    19             System.out.println("等待……"+i);//i值的不同,最后运行结果不同
    20         }
    21         
    22         System.out.println("线程开始执行之后……"+t.isAlive());
    23         for(int i=0;i<3;i++){
    24             System.out.println("main运行……"+i);
    25         }
    26         System.out.println("代码执行之后……"+t.isAlive());
    27     }
    28 }

    主线程有可能比其他线程先执行完,其他线程不会受到任何影响,不会随着主线程的结束而结束。

    线程的强制执行

    class MyThread implements Runnable{
        public void run(){
            for(int i=0;i<20;i++){
                System.out.println(Thread.currentThread().getName()+"运行……"+i);
            }
        }
    }
    
    public class ThreadJoinDemo {
    
        public static void main(String[] args) {
            MyThread mt = new MyThread();
            Thread t = new Thread(mt);
            t.start();
            for(int i=0;i<30;i++){
                if(i>10){
                    try{
                        t.join();
                    }catch(Exception e){}
                }
                System.out.println("Main线程"+i);
            }
        }
    }

    线程的休眠:

    sleep为静态方法,使用类名Thread直接调用

     1 class MyThread implements Runnable{
     2     public void run(){
     3         for(int i=0;i<5;i++){
     4             try{
     5                 Thread.sleep(1000);//每次输出都会间隔1000ms,达到延迟操作的结果
     6             }catch(Exception e){}
     7             System.out.println(Thread.currentThread().getName()+"…………"+i);
     8         }
     9     }
    10 }
    11 
    12 public class ThreadSleepDemo {
    13 
    14     public static void main(String[] args) {
    15         MyThread mt = new MyThread();
    16         new Thread(mt,"线程").start();
    17     }
    18 
    19 }

    线程的中断:

     1 class MyThread implements Runnable{
     2     public void run(){
     3         System.out.println("进入run方法");
     4         try{
     5             Thread.sleep(10000);
     6             System.out.println("已完成休眠");
     7         }catch(Exception e){
     8             System.out.println("休眠被终止");
     9             return;
    10         }
    11         System.out.println("正常结束");
    12     }
    13 }
    14 
    15 public class ThreadInterruptDemo {
    16     public static void main(String[] args) {
    17         MyThread mt = new MyThread();
    18         Thread t = new Thread(mt);
    19         t.start();
    20         try{
    21             Thread.sleep(2000);
    22         }catch(Exception e){}
    23         t.interrupt();        
    24     }
    25 }

    在使用joinsleep时,要进行异常处理。

    线程的礼让:

     1 class MyThread implements Runnable{
     2     public void run(){
     3         for(int i=0;i<5;i++){
     4             System.out.println(Thread.currentThread().getName()+"运行"+i);
     5             if(i==2){
     6                 System.out.print("线程礼让:");
     7                 Thread.currentThread().yield();
     8             }
     9         }
    10     }
    11 }
    12 
    13 public class ThreadYieldDemo {
    14 
    15     public static void main(String[] args) {
    16         MyThread mt = new MyThread();
    17         Thread t1 = new Thread(mt,"线程A");
    18         Thread t2 = new Thread(mt,"线程B");
    19         t1.start();
    20         t2.start();
    21     }
    22 }

    每当线程满足条件(i=2)时,本线程就会停止,而让其他线程先执行。

    同步:指多个操作在同一时间段内只能有一个线程进行,其他线程要等待此线程完成之后才可以继续进行。

    解决资源共享的同步操作,可以使用同步代码块和同步方法两种方式完成。

    同步代码块:

     1 class MyThread implements Runnable{
     2     private int ticket = 20;
     3     public void run(){
     4         for(int i=0;i<100;i++){
     5             synchronized(this){        //将当前对象(this)设置成同步对象
     6                 if(ticket>0){
     7                     System.out.println(ticket--);
     8                 }
     9             }
    10         }
    11     }
    12 }
    13 
    14 public class SynchronizedDemo {
    15 
    16     public static void main(String[] args) {
    17         MyThread mt = new MyThread();
    18         new Thread(mt).start();
    19         new Thread(mt).start();
    20         new Thread(mt).start();
    21     }
    22 }

    同步方法:(使用synchronized关键字将一个方法声明为同步方法)

     1 class MyThread implements Runnable{
     2     private int ticket = 50;
     3     public void run(){
     4         for(int i=0;i<100;i++){
     5             this.sale();
     6         }
     7     }
     8     private synchronized void sale() {
     9             if(ticket>0){
    10                 System.out.println(ticket--);
    11             }
    12     }
    13 }
    14 
    15 public class SynchronizedDemo {
    16 
    17     public static void main(String[] args) {
    18         MyThread mt = new MyThread();
    19         new Thread(mt).start();
    20         new Thread(mt).start();
    21         new Thread(mt).start();
    22     }
    23 }

    Java中方法定义的完整格式:

    访问权限(publicdefaultprotectedprivate[final][static][synchronized]

    返回值类型 void 方法名称(参数类型,参数名称)[throws Exception1,Exception2]

    {

    return 返回值;

    }

    死锁:指两个线程都在等着彼此先完成,造成了程序的停滞。

    卖票:同一个动作处理同一资源

    生产者消费者:不同动作处理同一资源

     1 class Info{
     2     private String name = "zhangsan";
     3     private String content = "java";
     4     private boolean flag = false;
     5     public synchronized void set(String name,String content){
     6         if(!flag){
     7             try{
     8                 super.wait();
     9             }catch(InterruptedException e){
    10                 e.printStackTrace();
    11             }
    12         }
    13         this.name = name;
    14         this.content = content;
    15         flag = false;
    16         super.notify();
    17     }
    18     public synchronized void get(){
    19         if(flag){
    20             try{
    21                 super.wait();
    22             }catch(InterruptedException e){
    23                 e.printStackTrace();
    24             }
    25         }
    26         System.out.println(name+ ":" +content);
    27         flag = true;
    28         super.notify();
    29     }
    30 }
    31 
    32 class Producer implements Runnable{
    33     private Info info = null;
    34     public  Producer(Info info){
    35         this.info = info;
    36     }
    37     public void run(){
    38         boolean flag = false;
    39         for(int i=0;i<10;i++){
    40             if(flag){
    41                 this.info.set("zhangsan", "java");
    42                 flag = false;
    43             }else{
    44                 this.info.set("wangzhi","www");
    45                 flag = true;    
    46             }
    47         }
    48     }
    49 }
    50 
    51 class Consumer implements Runnable{
    52     private Info info = null;
    53     public Consumer(Info info){
    54         this.info = info;
    55     }
    56     public void run(){
    57         for(int i=0;i<10;i++){
    58             try{
    59                 Thread.sleep(100);
    60             }catch(Exception e){
    61                 e.printStackTrace();
    62             }
    63             this.info.get();
    64         }
    65     }
    66 }
    67 
    68 public class ThreadCaseDemo {
    69 
    70     public static void main(String[] args) {
    71         Info i = new Info();
    72         Producer pro = new Producer(i);
    73         Consumer con = new Consumer(i);
    74         new Thread(pro).start();
    75         new Thread(con).start();
    76     }
    77 }

    停止线程运行:在多线程开发中可以通过设置标志位的方式停止一个线程的运行。

  • 相关阅读:
    四套读取方案
    java的分层开发
    位移运算符
    反射
    多线程下的单例
    学生管理系统
    iOS-分段控制器-基本概念
    iOS-UITableView-处理cell上按钮事件(弹出警示框,页面跳转等)
    iOS-UIScrollView-图片缩放
    Xcode-Xcode 7.3 解决不能自动联想问题
  • 原文地址:https://www.cnblogs.com/XuGuobao/p/7226344.html
Copyright © 2020-2023  润新知