java多线程编程(二创建线程)
1、概念
因为java是完全面向对象的,所以在java中,我们说的线程,就是Thread类的一个实例对象。所以,一个线程就是一个对象,它有自己字段和方法。
2、创建线程
创建线程有2种方法:1、扩展线程父类Thread类 , 2、实现Runnable接口。2种方法是由区别的。
提示:Thread类已经实现了Runnable接口,Thread类中不但实现了run方法,也定义了更多的,全面的线程对象的操作方法,而Runnable接口中只有run这一个方法。
通过扩展Thread类
public class Test {
public static void main(String[] args)
{
System.out.println("我是"+Thread.currentThread().getName()+"线程");
MyThread t1 = new MyThread("线程1");
MyThread t2 = new MyThread("线程2");
t1.start();
t2.start();
System.out.println(Thread.currentThread().getName()+"线程运行完毕");
}
}
class MyThread extends Thread
{
public MyThread()
{
super();
}
public MyThread(String name)
{
super(name);
}
@Override //重写父类的run方法
public void run()
{
for(int i=0;i<5;++i)
{
System.out.println("我是 "+this.getName());
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
输出:
我是main线程
main线程运行完毕
我是 线程2
我是 线程1
我是 线程1
我是 线程2
我是 线程1
我是 线程2
我是 线程1
我是 线程2
我是 线程2
我是 线程1
总结法发现:3个线程抢占CPU资源 ,快速交替执行,谁也不等谁,他们只等CPU。

通过实现Runnable接口
public class Test {
public static void main(String[] args)
{
MyThreadTest com = new MyThreadTest();
Thread t1 = new Thread(com,"线程1");
Thread t2 = new Thread(com,"线程2");
t1.start();
t2.start();
}
}
class MyThreadTest implements Runnable
{
private int num = 50;
@Override
public void run()
{
while(num>=1)
{
System.out.println("来自"+Thread.currentThread().getName()+" num = "+ num);
num--;
}
}
}
输出:(不同的机器和运行时间会输出不同的结果)
来自线程2 num = 10
来自线程1 num = 10
来自线程2 num = 9
来自线程1 num = 8
来自线程2 num = 7
来自线程1 num = 6
来自线程2 num = 5
来自线程1 num = 4
来自线程1 num = 2
来自线程1 num = 1
来自线程2 num = 3
我们发现线程1和线程2输出的数都不是完整的从10 ~1,因为他们2个程序共同操作一个“伪线程类“MyThreadTest 的实例,就是com。所以,当线程t1把num的值改为9的时候,这个时候t2访问到的num的值就是9了。这里涉及到线程同步的问题,我还在以后的随笔中讲解。
我为什么叫MyThreadTest叫“伪线程类”?因为MyThreadTest类根本就不是一个线程类。它和Thread虽然都实现了Runnable接口,但是MyThreadTest和Thread没有继承关系,我们前面说过,java中的线程是Thread类的一个实例。好比Rectangle类和Triangle类都实现了Shape接口,难道一个三角形可以看成一个矩形吗?显然是不可以的。
所以,我们通过Runnable接口去创建线程,还是需要借助Thread类。
Thread t1 = new Thread(com);
Thread t2 = new Thread(com);
因为t1和t2在构造时,使用的同一个“伪线程类”对象com ,所以t1 t2操作的就是同一个对象com 。如果你不想这样,那就分别为t1 t2提供不同的"伪线程类"对象
Thread t1 = new Thread(new MyThreadTest());
Thread t2 = new Thread(new MyThreadTest());
小结
一、一般我们建议实现Runnable,虽然多写一行代码,但这样更灵活,可扩展性强。
二、自定义线程中的run方法相当于主线程中的main方法,为什么要取名为main呢?因为这是java与系统之间的约定,main是程序入口的签名,他是一个标志,当java程序启动时,就会去调用名字为main 的方法。同理,一个新线程要执行它的业务逻辑代码,也需要一个约定好的名字:run。它和其他方法没有任何区别,只不过名字特殊而已。
3、Thread类中一些常用的线程操作方法(标有*的是要重点掌握的方法)
| *t.start() | 使t线程进入准备状态,能有被CPU执行的权利,但不一定马上被执行 |
| *t.run() | 不要自己显示调用run方法,当CPU给某个线程执行机会时,run方法就会自动执行。 |
| t.getName() | 返回此线程的名字 |
| t.setName(String name) | 设定线程的名字 |
| t.setPriority(int level) |
设定线程的优先级 Thread.MAX_PRIORITY 最高优先级,10 Thread.MIN_PRIORITY 最低优先级 1 Thread.NORM_PRIORITY 一般优先级 5 设置优先级后,JVM的事件调度器会根据线程的优先级来按顺序来调用线程。 通常高优先级线程会先于低优先级运行,但是这个规律不是总成立的。 优先级只会改变线程谁最先启动,和谁最后启动。CPU对每一个线程的单次执行时间片是固定的。 |
| t.getPriority() | 获取线程的优先级 |
| *t.join() | 线程合并。这句话写在哪个线程里面,就是让t1线程加入到那个线程的执行流程中。暂停执行这句话的线程,直到t1线程执行完毕后,在接着执行 。例如在main线程中有t1.join() ,执行到这个join函数时,main线程则暂,直到t1线程执行完毕, 在回来main接着执行。 |
| *t.isAlive() | 线程是否活着 |
| 静态方法: | |
| Thread.yield() | 该线程主动放弃被CPU执行的机会,让出CPU给相同优先级的线程,自己再次进入准备状态 ,下次会接着执行。这个方法的效果一般不会太明显,因为线程放弃CPU后再次进入准备阶段,而后又获得CPU的过程会很快。 |
| Thread.currentThread() | 反回当前正在运行的线程的引用 |
| *Thread.sleep(long millis) | 让线程睡眠millis毫秒,挂起,进入阻塞状态。此时CPU就会释放对此线程,而去 执行其它的线程睡眠时间过去后,该线程再次进入准备状态,等待被CPU执行。所以millis的值是至少的暂停时间。而不是绝对的暂停时间。 |
| 未完。。。待补充 |
java多线程编程(二创建线程)的更多相关文章
- Java多线程(二) —— 线程安全、线程同步、线程间通信(含面试题集)
一.线程安全 多个线程在执行同一段代码的时候,每次的执行结果和单线程执行的结果都是一样的,不存在执行结果的二义性,就可以称作是线程安全的. 讲到线程安全问题,其实是指多线程环境下对共享资源的访问可能会 ...
- Java 多线程(二) 线程的实现
线程的实现 在Java中通过run方法为线程指明要完成的任务,有两种技术来为线程提供run方法: 1.继承Thread类并重写它的run方法.之后创建这个子类的对象并调用start()方法. 2.通过 ...
- java多线程(二)-线程的生命周期及线程间通信
一.摘要 当我们将线程创建并start时候,它不会一直占据着cpu执行,而是多个线程间会去执行着这个cpu,此时这些线程就会在多个状态之间进行着切换. 在线程的生命周期中,它会有5种状态,分别为 ...
- iOS多线程编程之创建线程(转载)
一.创建和启动线程简单说明 一个NSThread对象就代表一条线程 (1)创建.启动线程 NSThread *thread = [[NSThread alloc] initWithTarget:sel ...
- (Java多线程系列二)线程间同步
Java多线程间同步 1.什么是线程安全 通过一个案例了解线程安全 案例:需求现在有100张火车票,有两个窗口同时抢火车票,请使用多线程模拟抢票效果. 先来看一个线程不安全的例子 class Sell ...
- Java 多线程(二)—— 线程的同步
上文创建多线程买票的例子中注释会出现错票.重票的问题,本文来讲讲如何解决此问题.本文例子:利用多线程模拟 3 个窗口卖票 实现Runnable接口 public class TestThread2 ...
- iOS多线程编程之创建线程安全(转载)
一.多线程的安全隐患 资源共享 1块资源可能会被多个线程共享,也就是多个线程可能会访问同一块资源 比如多个线程访问同一个对象.同一个变量.同一个文件 当多个线程访问同一块资源时,很容易引发数据错乱和数 ...
- java多线程(二)线程的生命周期
1. 线程生命周期 新建(New).就绪(Runnable).运行(Running).阻塞(Blocked)和死亡(Dead)5种状态. 1.1. 新建 l new关键字创建了一个线程之后,该线 ...
- java多线程编程(二)
1. wait 和 sleep 区别? 1.wait可以指定时间也可以不指定,sleep必须指定时间. 2.在同步中时,对cpu的执行权和锁的处理不同. wait:释放执行权,释放锁. sleep ...
随机推荐
- Python实践:开篇
一.概述 Python实践 是应用Python解决实际问题的案例集合,这些案例中的Python应用通常 功能各异.大小不一. 该系列文章是本人应用Python的实践总结,会不定期更新. 二.目录 Py ...
- git学习 本地常用操作01
注意: Microsoft的Word格式是二进制格式,因此,版本控制系统是没法跟踪Word文件的改动 不要使用Windows自带的记事本编辑任何文本文件 开始git项目: 初始化本地项目: 初始化:g ...
- 简单几何(点与线段的位置) POJ 2318 TOYS && POJ 2398 Toy Storage
题目传送门 题意:POJ 2318 有一个长方形,用线段划分若干区域,给若干个点,问每个区域点的分布情况 分析:点和线段的位置判断可以用叉积判断.给的线段是排好序的,但是点是无序的,所以可以用二分优化 ...
- White Rectangles[HDU1510]
White Rectangles Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
- Codeforces Round #199 (Div. 2) A Xenia and Divisors
注意题目的数字最大是7 而能整除的只有 1,2,3,4,6,故构成的组合只能是1,2,4 或1,2,6或1,3,6,故分别统计1,2,3,4,6的个数,然后再分配 #include <iostr ...
- BestCoder Round #78 (div.2)
因为rating不够QAQ就报了Div2.. [CA Loves Stick] CA喜欢玩木棍. 有一天他获得了四根木棍,他想知道用这些木棍能不能拼成一个四边形. Sample Input 2 1 1 ...
- android怎样调用@hide和internal API
android怎样调用@hide和internal API 2012-12-11 16:21 8772人阅读 评论(3) 收藏 举报 分类: Android开发(277) Android有两种类型 ...
- iOS5中UIViewController的新方法
iOS5中UIViewController的新方法 前言 在苹果的 WWDC2011 大会视频的<Session 101 - What's New in Cocoa> 和<Sessi ...
- c++模版函数
1.定义 可以使用class或者typename字段来申明 template <class T> template <class T1, class T2, ...class TN& ...
- IOS第四天(6:答题区按钮点击和乱序)
#pragma mark - 答题区按钮点击方法 - (void)answerClick:(UIButton *)button { // 1. 如果按钮没有字,直接返回 ) return; // 2. ...