黑马程序员《多线程(一创建线程的两种方式)》
2015-03-27 22:42
465 查看
---------------------------ASP.Net+Android+IOS开发、java培训、期待与您交流!
---------------------------------
一、线程概念
1、什么是线程?什么是进程?
进程:是一个正在执行中的程序。每一个进程执行都有一个执行顺序。该顺序是一个执行路径,或者叫一个控制单元。线程:就是进程中的一个独立的控制单元,线程在控制着进程的执行,一个进程中至少有一个线程。
java vm 启动时会有一个进程java.exe,该进程中至少一个线程负责java程序的执行。
而且这个线程运行的代码存在于main方法中,该线程称之为主线程。
扩展:其实更细节说明jvm,jvm启动不止一个线程,还有负责垃圾回收机制的线程。
2、如何在一个自定义的代码中,自定义一个线程呢?
通过api的查找,java已经提供了对线程这类事物的描述,就Thread类。创建线程的第一种方式:继承Thread类。
步骤:1、定义类继承Thread.
2、复写Thread类中run方法。
3,调用线程的start方法。
代码:创建线程并启动
PrimeThread p = new PrimeThread(143);
p.start();
实例:class PrimeThread extends Thread
{ long minPrime;
PrimeThread(long minPrime) {
this.minPrime = minPrime;
} public void run()
{ // compute primes larger than minPrime
. . .}
}
创建线程的第二种方式:
代码:创建并启动一个线程
PrimeRun p = new PrimeRun(143);
new Thread(p).start();
代码:实例Runnable接口
class PrimeRun implements Runnable {
long minPrime;
PrimeRun(long minPrime) {
this.minPrime = minPrime; }
public void run() { // compute primes larger than minPrime
. . . } }
该方法两个作用,启动线程,调用run方法。发现运行结果每一次都不同。因为多个线程都获取cpu的执行权。cpu执行到谁,谁就运行。
明确一点,在某一时刻,只能有一个程序在运行。(多核除外)
cpu在做着快速切换,已达到看上去是同时运行的效果。
互相抢夺cpu的执行权,多线程的特点:随机性。
3、 为什么要覆盖run方法呢?
下面以一个例子来演示这种使用线程的方法,首先创建一个Thread类的子类,并覆盖Thread类中的run()方法。
package com.javaeasy.usethread; // 程序所在的包
public class MyThread extends Thread { //
MyThread类继承自Thread类
public void run() { //
覆盖Thread类中的run()方法
System.out.println("这是在另一个线程中执行的代码。");
//
向控制台输出一行字
} //
run()方法结束
}
上面的类很简单。首先需要注意的就是MyThread类继承自Thread类,然后是MyThread类覆盖了Thread类中的run()方法。这样才能够让线程在启动后(调用start()方法后)执行到想让线程执行的内容。好,下面是一个使用MyThread类的例程。
package com.javaeasy.usethread; // 程序所在的包
public class UseMyThread { // 例程类
public static void main(String[] args) { // main()方法
MyThread thread = new MyThread(); //
创建一个Thread类的实例
thread.start(); //
启动一个新的线程
}
}
二、创建线程第二种方式:实现Runable接口
(1)实现Runnable接口步骤:1、定义类实现Runnable接口
2、覆盖Runnable接口中的run方法。将线程要运行的代码存放在该run方法中。
3、通过Thread类建立线程对象。
4、将Runnable接口的子类对象作为实际参数传递给Thread类中的构造函数。
1)为什么要将Runnable接口的子类对象传递给Thread的构造函数。
答:因为自定义的run方法所属的分对象是Runnable接口的子类对象。
所以要让线程去执行指定对象的run方法。就必须明确该run方法所属对象。
5、调用Thread类的start方法开启线程并调用Runnable接口子类的run方法。
(2)实现方式和继承方式有什么区别呢?
实现方式好处:避免了单继承的局限性。
在定义线程时,建立使用实现方式。
两种方式区别:
继承Thread:线程代码存放Thread子类run方法中。
实现Runnable,线程代码存在接口的子类的run方法。
(3)多线程的运行出现了安全问题。
问题的原因:
当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没有执行完,另一个线程参与进来执行。导致共享数据的错误。
解决办法:
对多条操作共享数据的语句,只能让一个线程都执行完。在执行过程中,其他线程不可以参与执行。
Java对于多线程的安全问题提供了专业的解决方式。
就是同步代码块。
synchronized(对象)
{
需要被同步的代码
}
对象如同锁。持有锁的线程可以在同步中执行。
没有持有锁的线程即使获取cpu的执行权,也进不去,因为没有获取锁。
(4)代码
class Ticket implements Runnable//extends Thread
{
private int tick = 1000;
Object obj = new Object();
public void run()
{
while(true)
{
synchronized(obj)
{
if(tick>0)
{
//try{Thread.sleep(10);}catch(Exception e){}
System.out.println(Thread.currentThread().getName()+"....sale : "+ tick--);
}
}
}
}
}
class TicketDemo2
{
public static void main(String[] args)
{
Ticket t = new Ticket();
Thread t1 = new Thread(t);//创建了一个线程;
Thread t2 = new Thread(t);//创建了一个线程;
Thread t3 = new Thread(t);//创建了一个线程;
Thread t4 = new Thread(t);//创建了一个线程;
t1.start();
t2.start();
t3.start();
t4.start();
}
}
---------------------------ASP.Net+Android+IOS开发、java培训、期待与您交流!
---------------------------------
相关文章推荐
- 黑马程序员_java创建线程的两种方式
- 多线程-01,创建线程的两种方式
- 多线程1:两种方式创建线程示例
- 黑马程序员——多线程--线程的创建方式和线程安全的简单介绍
- 黑马程序员:创建线程的两种方式
- 黑马程序员:创建线程的两种方式
- 黑马程序员--创建线程的两种方式、步骤以及代码体现
- 黑马程序员——创建线程的两种方式
- java多线程总结一:线程的两种创建方式及优劣比较
- 黑马程序员——java创建线程的两种创建方式
- 黑马程序员——JAVA基础之简述多线程,两种创建多线程的方式
- 黑马程序员--04.多线程--03.【创建线程两种方法的对比】【多线程卖票案例设计】
- 多线程_Thread类简介及创建线程的两种方式
- 黑马程序员--04.多线程--01.【线程的基本概念】【线程的创建方式】
- JAVA·多线程:创建线程的两种方式
- 多线程的安全问题。 创建线程的两种方式区别
- java多线程总结一:线程的两种创建方式及优劣比较
- 黑马程序员-线程(两种创建方式)、定时器
- java多线程总结一:线程的两种创建方式及优劣比较
- 黑马程序员--Java学习笔记之多线程(自定义线程的两种方式对比、线程状态、线程安全)