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 }

 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 }

 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 }

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

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

区别:

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 }
时间: 2024-09-27 02:18:27

Java基础笔记-多线程的相关文章

[Java基础笔记]数组

Java基础笔记 定义数组: int[] numbers = new int[100]; //方法一 double[] num = new double[10]; int[][] a = new int[2][5]; 通过new创建的数组,元素默认值为0(0.0) int[] scores = {5,4,33,12,46}; //方法二 int[][] a = { //位数不足,自动补0 {5,3,2,1,6}, {10,12,14,15}, }; 数组特性:存储的都是同类型数据:长度定义后不可

java 基础笔记 基本数据类型对象包装类

基本数据类型对象包装类: 为了方便操作基本数据类型值,将其封装成了对象,在对象中定义了属性和行为丰富了该数据的操作. 用于描述该对象的类就称为基本数据类型对象包装类. 基本数据类型 包装类 byte Byte short Short int Integer long Long float Float double Double char   Character boolean Boolean 该包装对象主要用于基本类型和字符串之间的转换. 基本类型-->字符串 1.基本类型数据+"&quo

Java基础笔记 – Annotation注解的介绍和使用 自定义注解

Java基础笔记 – Annotation注解的介绍和使用 自定义注解 本文由arthinking发表于5年前 | Java基础 | 评论数 7 |  被围观 25,969 views+ 1.Annotation的工作原理:2.@Override注解:3.@Deprecated注解:4.@SuppressWarnings注解:5.自定义注解:5.1.添加变量:5.2.添加默认值:5.3.多变量使用枚举:5.4.数组变量:6.设置注解的作用范围:6.1.在自定义注解中的使用例子:7.使用反射读取R

【转】Java基础笔记 – 枚举类型的使用介绍和静态导入--不错

原文网址:http://www.itzhai.com/java-based-notes-introduction-and-use-of-an-enumeration-type-static-import.html#1.2.values方法的使用: Java基础笔记 – 枚举类型的使用介绍和静态导入 本文由arthinking发表于4年前 | Java基础 | 暂无评论 |  被围观 8,332 views+ 1.枚举(Enum):1.1.枚举类型中的两个静态方法:1.2.values方法的使用:

JAVA学习笔记 -- 多线程之共享资源

在多线程程序运行过程中,可能会涉及到两个或者多个线程试图同时访问同一个资源.为了防止这种情况的发生,必须在线程使用共享资源时给资源"上锁",以阻挡其它线程的访问.而这种机制也常常被称为互斥量,本文主要介绍它的两种方式synchronized和Lock . 1.synchronized 当任务要执行被synchronized关键字保护的代码片段的时候,它会检查锁是否可用,然后获取锁,执行代码,释放锁.synchronized也有两种用法: A.synchronized方法 import

黑马程序员----java基础笔记中(毕向东)

<p>------<a href="http://www.itheima.com" target="blank">Java培训.Android培训.iOS培训..Net培训</a>.期待与您交流! -------</p><p> </p><p>笔记一共记录了毕向东的java基础的25天课程,分上.中.下</p><p>本片为中篇,涵盖11-20天课程</p&

Java学习笔记—多线程(java.util.concurrent并发包概括,转载)

一.描述线程的类:Runable和Thread都属于java.lang包 二.内置锁synchronized属于jvm关键字,内置条件队列操作接口Object.wait()/notify()/notifyAll()属于java.lang包 二.提供内存可见性和防止指令重排的volatile属于jvm关键字 四.而java.util.concurrent包(J.U.C)中包含的是java并发编程中有用的一些工具类,包括几个部分: 1.locks部分:包含在java.util.concurrent.

java 基础笔记 第一波~

Java 基础知识  首次复习. 1.作用域 其实就是这个变量可以起作用的范围. 2.有时候碰到的 value ,其实就一个变量名 ,别想的太复杂. 3.Java 局部变量,实例变量 ,类变量(静态变量)区别 1,局部变量 是类的方法中的变量: 2.实例变量 类中独立于方法之外的变量 不过没有static修饰 也叫对象变量 3.类变量(静态变量) 类中独立于方法之外的变量 用static修饰 也叫静态变量 伪代码说明 Public class Variable{ Static int allcl

【BigData】Java基础_多线程

所谓的多线程就像小吃街卖铜锅米线的老板,老板就好比一个操作系统,如果5个顾客同时去买米线,那么,此时老板就会同时准备好5个铜锅,然后同时放上水.调料.米线,同时煮5个人的米线,如果逐个煮的话,那么估计煮了2个人的米线,后面3人就来找老板退款了. 官方解释:多线程(英语:multithreading),是指从软件或者硬件上实现多个线程并发执行的技术 在Java中实现多线程四部曲: (1)将需要用多线程方式执行的逻辑,写入一个runnable实现类中(run方法中): (2)创建出这个runnabl