实现
方法一:继承Thread类
package com;
public class demo1 {
public static void main(String[] args) {
MyThread myThread = new MyThread("a"); // 创建线程对象
myThread.start(); // 启动线程
}
}
class MyThread extends Thread{
public MyThread(String name) {
super(name);
}
@Override
public void run() {
System.out.println("线程" + Thread.currentThread().getName()); // 获得当前线程的线程名
}
}
结果:
线程a
- 步骤,继承Thread类,重写run()方法,创建线程对象,调用start()启动线程
- 此例中涉及到的Thread中方法:
-
- start() 启动线程,将线程放入就绪队列等待操作系统调度,注意不是立即执行,调度后执行run()方法
- run() 需要子类重写
- currentThread() 返回对当前正在执行的线程对象的引用
- getName() 返回此线程的名称
- main()方法也是一个线程,叫主线程
方法二:实现Runnable接口
package com;
public class demo2 {
public static void main(String[] args) {
MyRun myRun = new MyRun(); // 创建目标对象
Thread thread = new Thread(myRun, "a"); // 创建线程对象
thread.start(); // 开启线程
// new Thread(myRun, "a").start();
}
}
class MyRun implements Runnable{
@Override
public void run() {
System.out.println("线程" + Thread.currentThread().getName());
}
}
-
实现Rubbable接口,重写run()方法,创建目标对象,创建线程对象,调用start()启动线程
-
MyRun类的对象不是线程对象
-
Thread类实现了Runnable接口
状态
- 生命周期:
-
在Thread.State类中定义了6中状态:
-
NEW
尚未启动的线程处于此状态。
RUNNABLE
在Java虚拟机中执行的线程处于此状态。
BLOCKED
被阻塞等待监视器锁定的线程处于此状态。
WAITING
正在等待另一个线程执行特定动作的线程处于此状态。
TIMED_WAITING
正在等待另一个线程执行动作达到指定等待时间的线程处于此状态。
TERMINATED
已退出的线程处于此状态。 -
方法:getState() 返回此线程的状态
多线程的效果
package com;
public class demo2 {
public static void main(String[] args) {
MyRun myRun = new MyRun(); // 创建目标对象
new Thread(myRun, "a").start(); // 创建线程对象
new Thread(myRun, "b").start(); // 创建线程对象
}
}
class MyRun implements Runnable{
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
System.out.println("线程" + Thread.currentThread().getName());
}
}
}
一部分结果:
线程a
线程a
线程b
线程b
线程b
线程b
线程b
线程b
线程b
线程a
线程a
线程a
优先级
共有10个优先级
下面是定义好的三个常量
/**
* The minimum priority that a thread can have.
*/
public final static int MIN_PRIORITY = 1;
/**
* The default priority that is assigned to a thread.
*/
public final static int NORM_PRIORITY = 5;
/**
* The maximum priority that a thread can have.
*/
public final static int MAX_PRIORITY = 10;
-
优先级高的不一定先执行
-
方法:
getPriority() 返回此线程的优先级
setPriority(int newPriority) 更改此线程的优先级
其他方法
- sleep() 使当前正在执行的线程以指定的时间睡眠
package com.demo2;
public class TestSleep {
public static void main(String[] args) {
MySleep m1 = new MySleep();
new Thread(m1).start();
}
}
class MySleep implements Runnable {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(i);
try {
Thread.sleep(1000); // sleep
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
- yield() 当前线程进入就绪状态,与其他线程重新竞争资源,注意,不是说让给其他线程自己就不参与竞争了
- join() 等待这个线程死亡 (效果看例子)
package com.demo2;
public class TestJoin extends Thread{
@Override
public void run() {
for (int i = 0; i < 2000; i++) {
System.out.println("插队" + Thread.currentThread().getName());
}
}
public static void main(String[] args) throws InterruptedException {
TestJoin testJoin = new TestJoin();
testJoin.start();
for (int i = 0; i < 500; i++) {
if(i == 200){
testJoin.join(); // join
}
System.out.println("main"+ i);
}
}
}
/*
这有main线程和testJoin两个线程
当main执行到i==200时要等testJoin线程执行完再继续执行
结果:
.
.
main193
插队Thread-0
插队Thread-0
插队Thread-0
main194
main195
插队Thread-0
main196
main197
main198
main199 从这开始,main要等Thread-0执行完再继续执行
插队Thread-0
插队Thread-0
插队Thread-0
插队Thread-0 省略部分全是Thread-0
.
.
.
插队Thread-0
插队Thread-0
插队Thread-0
插队Thread-0
main200
main201
main202
main203
main204
main205 后面全是main了
.
main499
*/
- 等等
同步
使用synchronized声明临界区
wait()方法,让无法进行数据存取的线程暂时进入休眠状态
notify(),唤醒处于休眠状态的线程,通常由线程对象调用
notifyall(),一次唤醒所有
- 下例中,需求:只有用户将money存入账户后银行才能扣款
class Account{
private int Credit;
private boolean available = false;
// 存款方法
public synchronized void put(int money){
//当get()未执行时,等待get()方法执行
while (available == true){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Credit = money;
// 告知get()方法款项已存入,可执行扣款操作
available = true;
notifyAll();
}
// 扣款方法
public synchronized int get(){
//当put()未执行时,等待put()方法执行
while (available == false){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 告知put()方法应缴款项已扣除,可以执行存款操作
available = false;
notifyAll();
return Credit;
}
}
其他
1、Timer和TimerTask
package com;
import java.util.Timer;
import java.util.TimerTask;
public class demo1 {
public static void main(String[] args) {
MyTask myTask = new MyTask();
Timer timer = new Timer();
timer.schedule(myTask, 10, 10); // 前面任务延迟,后面跟着延迟
timer.scheduleAtFixedRate(myTask, 10 ,10); // 无论上一次任务是否结束,间隔一到立即执行
}
}
class MyTask extends TimerTask{
@Override
public void run() {
System.out.println("yahou");
}
}
2、Callable接口:
https://www.jb51.net/article/145487.htm
https://blog.youkuaiyun.com/niuzhucedenglu/article/details/80525432
本文参考源码、jdk api文档、《java从入门到精通》明日学院 编著、《java程序设计与计算思维》 赵军 吴灿铭编著