zoukankan      html  css  js  c++  java
  • Java基础笔记-多线程

    线程:

    方式一:继承Thread类并且复写run方法.

    格式:

    class MyThread extends Thread

    {

      public void run()

      {

        线程中要运行的代码.

      }

    }

    其步骤为:

    1.定义类继承Thread类.

    2.复习run方法.---->目的是:用于存储线程中要运行的代码,将自定义的代码存储在run方法中,让线程运行.

    3.调用线程的start方法

      注意:不是调用run方法.

    线程的名字:一般线程有默认的名字,形式为:Thread-编号,编号是从0开始标记的.

    也可以获取当前运行线程的名字,用方法:Thread.currentThread().getName()

    Thread.currentThread() 是用于获取当前线程的对象.(静态的).

    自定义设置线程的名字可以用setName()或者构造函数来设置.

    有关线程的继承方式的代码实例和练习:

     1 /*
     2 线程:步骤:
     3 1.定义一个类继承Thread
     4 2.复写类中的润方法
     5 3.创建一个对象(创建一个对象也就创建了一个线程)
     6 4.调用线程的start()方法,调用start方法后,启动了线程,同时也调用了run()方法.
     7 */
     8 class MyThread extends Thread //第一步
     9 {
    10     public void run() //第二步
    11     {
    12         for(int x = 0; x < 60; x++)
    13             System.out.println("MyThread run!====="+x);
    14     }    
    15 }
    16 
    17 
    18 class ThreadDemo
    19 {
    20     public static void main(String args[])
    21     {
    22         MyThread mt = new MyThread();//创建了一个线程. //第三步
    23         mt.start(); // 开启线程并运行该线程的run方法.     //第四步
    24         //mt.run(); // 仅仅是对象调用方法,虽然创建了线程,但并未运行线程.
    25         
    26         for(int x = 0; x < 60; x++)
    27             System.out.println("Hello World!====="+x);
    28     }
    29 }
    View Code
     1 /*
     2 
     3 */
     4 class FirstThread extends Thread
     5 {
     6     //private String name;
     7     FirstThread(String name)
     8         {
     9             //this.name = name;
    10             super(name); 
    11         }
    12     public void run()
    13     {
    14         for(int i = 1; i <= 50; i++)
    15         {
    16             //System.out.println(this.name+"FirstThread run.====="+i);
    17             System.out.println((Thread.currentThread()==this)+"......"+this.getName()+"FirstThread run.====="+i);
    18         }
    19     }
    20 }
    21 
    22 class ThreadTest
    23 {
    24     public static void main(String args[])
    25     {
    26         FirstThread ft1 = new FirstThread("First===");
    27         FirstThread ft2 = new FirstThread("Second===");
    28         ft1.start();
    29         ft2.start();
    30         
    31         for(int i = 1; i <= 50; i++)
    32         {
    33             System.out.println("mainThread run.====="+i);
    34         }
    35     }
    36 }
    View Code
     1 /*
     2 售票窗口例子:
     3 多个窗口能够同时卖票.
     4 */
     5 
     6 class Ticket extends Thread
     7 {
     8     private static int ticket = 100; //不用static时候.两个窗口都会同时卖同号的票,即100张票连个窗口都会卖一次(相当于卖了200次)
     9     Ticket(String name)
    10     {
    11         super(name);
    12     }
    13     public void run()
    14     {
    15         while(true)
    16         {
    17             if(ticket>0)
    18             {
    19                 System.out.println(Thread.currentThread().getName()+"===卖票===="+ticket--);
    20             }
    21         }
    22     }
    23 }
    24 
    25 
    26 class TicketDemo
    27 {
    28     public static void main(String args[])
    29     {
    30         Ticket t1 = new Ticket("窗口1");
    31         Ticket t2 = new Ticket("窗口2");
    32         t1.start();
    33         t2.start();
    34         
    35     }
    36 }


    线程的第二种方式:

    实现Runnable接口:

    格式为:

    class MyRunnable implements Runnable

    {

      public void run()

      {

         线程中要运行的有关代码.

      }

    其步骤一般为:

    1.定义一个类实现Runnable接口.

    2.复写Runnable接口中的run方法.

    3.通过Thread类来创建一个对象.

    4.将Runnable的子类的对象作为实际参数传给Thread类中的构造函数.

    5.调用Thread类中的start方法.开启线程,并调用Runnable接口的子类的run方法.(可以理解为run方法又start方法开启调用的)

    例如:

    class MyRunnable implements Runnable  //步骤1

    {

      public void run()  //步骤2

      {

        S.o.p();

      }

    }

    class RunnableDemo

    {

      p.s.v.main()

      {

        MyRunnable mr = new MyRunnable();

        Thread t1 = new Thread(mr);  //步骤3---4

        t1.start();    //步骤5

      }

    }

     1 /*
     2 售票窗口例子:
     3 多个窗口能够同时卖票.
     4 不使用静态的ticket来完成每个窗口的卖票,且不会卖重复的票.
     5 通过实现Runnable接口来完成.
     6 
     7 创建线程的第二种方法:
     8 实现Runnable接口来完成.
     9 步骤:
    10 1.定义一个类实现(implements)Runnable接口
    11 2.复写Runnable接口中的run方法
    12 3.通过Thread类来创建对象
    13 4.将Runnable接口的子类对象作为实际参数传给Thread类中的构造函数.
    14 5.调用Thread类中的start方法开启线程,并调用Runnable接口的子类的run方法.
    15 */
    16 
    17 
    18 class Ticket implements Runnable
    19 {
    20     private int ticket = 100;  //    private static int ticket = 100; 
    21     /*
    22     由于Ticket并未继承Thread,该类并没有getName()的方法,因此是不能调用的.
    23     Ticket(String name)
    24     {
    25         super(name);
    26     }
    27     */
    28     public void run()
    29     {
    30         while(true)
    31         {
    32             if(ticket>0)
    33             {
    34                 System.out.println(Thread.currentThread().getName()+"===卖票====="+ticket--);
    35             }
    36         }
    37     }
    38 }
    39 
    40 
    41 class RunnableTicketDemo
    42 {
    43     public static void main(String args[])
    44     {
    45         Ticket t = new Ticket();  //t是共享数据.
    46         
    47         /*
    48         下面的方法不静态ticket时候会出现卖了200张票的情况,如何不静态 ticket =100,也自定义线程名且不出现卖200张票的情况????
    49         */
    50         //Ticket tt = new Ticket();
    51         //Ticket ttt = new Ticket();
    52         //Ticket tttt = new Ticket();
    53         
    54         //Thread t1 = new Thread(t,"窗口1");
    55         //Thread t2 = new Thread(tt,"窗口2");
    56         //Thread t3 = new Thread(ttt,"窗口3");
    57         //Thread t4 = new Thread(tttt,"窗口4");
    58         /*
    59         下面的代码执行后,Thread.currentThread().getName()获取的是默认的线程名.
    60         */
    61         Thread t1 = new Thread(t);
    62         Thread t2 = new Thread(t);
    63         Thread t3 = new Thread(t);
    64         Thread t4 = new Thread(t);
    65         
    66         t1.start();
    67         t2.start();
    68         t3.start();
    69         t4.start();
    70     }
    71 }
    View Code

    继承方式和实现方式的多态的区别和特点:

    实现方式:避免了单继承的局限性.一般定义线程时,建议使用实现方式.

    区别:

    1.继承Thread:线程代码存放在Thread的子类的run方法中.

    2.实现Runnabel:线程的代码存放在Runnable接口的子类的run方法中.

    最后是同步代码块,解决了多线程的安全性问题

    格式为:

    synchronized(对象)

    {

    需要被同步的代码块.

    }

    有关实现Runnable接口和同步的示例和练习代码:

     1 /*
     2 多线程的安全问题;
     3    打印出了票数为0.-1.-2等问题.
     4  
     5 问题分析,多条语句同时使用同一线程的共享数据时,一个线程只执行了一部分,还未执行完,另一个线程就参与进来执行了,导致共享数据的错误.
     6                     在if判断中,当ticket=1时,一个线程进去执行语句后,另一个线程也执行进来.
     7                     此时的ticket已经通过ticket--变成了0,从而导致了输出票数为0或者负数的情况.
     8 解决方案:
     9                     对操作多条共享数据的语句,让一个线程完全执行完毕后才让另一个线程执行,从而避免这种问题的发生.
    10                     
    11                     同步代码块.关键字:synchronized
    12                     格式:
    13                     synchronized(对象)
    14                     {
    15                         需要被同步的代码.
    16                     {
    17                     
    18                     同步的条件:
    19                     1.必须是多线程,单线程不能用同步.
    20                     2.必须是多个线程使用同一个锁.
    21                     必须保证同步中只有一个线程在运行.
    22                     
    23 同步的好处:解决了多线程的安全性问题.
    24 缺点:每个线程都要判断锁,影响程序运行速度,耗费资源.
    25 */
    26 class Ticket implements Runnable
    27 {
    28     private int ticket = 100; 
    29     Object obj = new Object();
    30     public void run()
    31     {
    32         while(true)
    33         {
    34             synchronized(obj) //obj相当于锁.
    35             {
    36                 if(ticket>0)
    37                 {
    38                     // try{Thread.sleep(10);}catch(Exception e){}
    39                     System.out.println(Thread.currentThread().getName()+"===卖票====="+ticket--);
    40                 }
    41             }
    42         }
    43     }
    44 }
    45 
    46 class RunnableTicketSafeDemo
    47 {
    48     public static void main(String args[])
    49     {
    50         Ticket t = new Ticket();  //t是共享数据.
    51         
    52         Thread t1 = new Thread(t);
    53         Thread t2 = new Thread(t);
    54         Thread t3 = new Thread(t);
    55         Thread t4 = new Thread(t);
    56         
    57         t1.start();
    58         t2.start();
    59         t3.start();
    60         t4.start();
    61     }
    62 }
  • 相关阅读:
    餐饮点菜控件
    数据模块池
    关于sqlite数据库
    PHP使用DateTime类做时间日期到字符串转换
    php字符串比较函数
    Xdebug开源PHP程序调试器
    ubuntu chmod 无法更改 文件夹权限 系统提示“不允许的操作 2、linux 如何修改只读文件 3、ubuntu安装
    ubuntu的命令day1
    linux用终端上传文件和文件家到远程的服务器
    Symfony学习--原创。。。。
  • 原文地址:https://www.cnblogs.com/jerryho/p/4523448.html
Copyright © 2011-2022 走看看