文章目录
- 1、什么是线程
- 2、线程的组成
- 3、线程的特点
- 4、线程的创建方式
- 5、获取和设置线程的名称
- 6、示例
- 使用线程Thread类实现4个窗口各卖100张票
- 实现四个窗口共卖100张票
- 7、线程的状态
- 8、 常见方法
- 9、线程的状态(等待)
1、什么是线程
线程,又称轻量级进程(Light Weight Process)。
进程中的一条执行路径,也是CPU的基本调度单位。
一个进程由一个或多个线程组成,彼此间完成不同的工作,
同时执行,称为多线程。
2、线程的组成
任何一个线程都具有基本的组成部分
1)CPU时间片: 操作系统(OS)会为每个线程分配执行时间
2)运行数据:
堆空间: 存储线程需要的对象,多个线程可以共享堆中的数据。
栈空间: 存储线程需使用的局部变量,每个线程都拥有独立的栈。
3)线程的逻辑代码.
3、线程的特点
1. 线程抢占式执行
效率高
可防止单一线程长时间独占CPU.
2. 在单核CPU中,宏观上同时执行,微观上顺序执行
4、线程的创建方式
1. 【继承Thread类,重写run方法】
2. 【实现Runnable接口】
3. 实现Callable接口
5、获取和设置线程的名称
获取线程ID和线程名称
1. 在Thread的子类中调用this.getId()或this.getName()
2. 使用Thread.currentThread().getId()和
3.Thread.currentThread().getName()
修改线程名称
1. 调用线程对象的setName()方法
2. 使用线程子类的构造方法赋值
6、示例
使用线程Thread类实现4个窗口各卖100张票
package com.zsb.demo01;
public class MyThread extends Thread{
@Override
public void run(){
for (int i=99;i>=0;i--){
System.out.println(Thread.currentThread().getName()+"卖票1张===还有"+i+"张");
}
}
}
package com.zsb.demo01;
public class Test02 {
public static void main(String[] args) {
MyThread m1 = new MyThread();
m1.setName("窗口1");
MyThread m2 = new MyThread();
m2.setName("窗口2");
MyThread m3 = new MyThread();
m3.setName("窗口3");
MyThread m4 = new MyThread();
m4.setName("窗口4");
m1.start();
m2.start();
m3.start();
m4.start();
//
// for (int i=1;i<10;i++){
// System.out.println("45454========"+i);
// }
}
}
实现四个窗口共卖100张票
package com.zsb.demo15;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Test {
public static void main(String[] args){
//创建了四个窗口
TicketSell r1 = new TicketSell();
Thread t1 = new Thread(r1);
Thread t2 = new Thread(r1);
Thread t3 = new Thread(r1);
Thread t4 = new Thread(r1);
t1.setName("窗口1");
t2.setName("窗口2");
t3.setName("窗口3");
t4.setName("窗口4");
t1.start();
t2.start();
t3.start();
t4.start();
}
static class TicketSell implements Runnable {
//定义总票数为100张
private int ticket = 100;
Lock s = new ReentrantLock();
@Override
public void run() {
while (true) {
try {
s.lock();
if (ticket > 0) {
try {
Thread.sleep(100);//等待一定的时间
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "卖出 1 张票," + " 还剩" + (ticket - 1) + " 张票!");
ticket--;
} else {
System.out.println(Thread.currentThread().getName() + "票已售完");
break;
}
} finally {
s.unlock();
}
}
}
}
}
7、线程的状态
8、 常见方法
休眠:
public static void sleep(long millis)
当前线程主动休眠millis毫秒。
package com.zsb.demo04;
public class TestSleep {
public static void main(String[] args) {
T t = new T();
t.start();
for (int i = 0; i < 20; i++) {
System.out.println("main===="+i);
}
}
}
class T extends Thread{
@Override
public void run(){
for (int i = 0; i < 20; i++) {
try {
Thread.sleep(100);
}catch (InterruptedException e){
e.printStackTrace();
}
System.out.println("============="+i);
}
}
}
放弃:
public static void yield()
当前线程主动放弃时间片,回到就绪状态,竞争下一次时间片
加入:
public final void join()
允许其他线程加入到当前线程中
package com.zsb.demo08;
public class TestJoin {
public static void main(String[] args) throws InterruptedException {
T3 t3 = new T3();
t3.start();
//把t线程加入到当前得main线程中,直到t执行完毕后, main才会执行
t3.join();
for (int i = 0; i < 20; i++) {
System.out.println("main________"+i);
}
}
}
class T3 extends Thread{
@Override
public void run(){
for (int i = 0; i < 20; i++) {
System.out.println("============="+i);
}
}
}
优先级:
线程对象.setPriority()
线程优先级1-10,默认为5,优先级越高,表示获取CPU的概率越高
守护线程:
线程对象.setDaemon(true);设置为守护线程。
线程有两类:用户线程(前台线程)和守护线程(后台线程)
如果程序中所有前台线程都执行完毕了,后台线程也会自动结束。
垃圾回收线程属于守护线程。
package com.zsb.demo09;
public class TestDaemon {
public static void main(String[] args) {
T4 t4 = new T4();
// 设置t4为守护线程,当前台线程都执行完毕后,守护线程也会自动结束
t4.setDaemon(true);
t4.start();
for (int i = 0; i < 20; i++) {
System.out.println("main________"+i);
}
}
}
class T4 extends Thread{
@Override
public void run(){
for (int i = 0; i < 20; i++) {
System.out.println(Thread.currentThread().getName()+"============="+i);
}
}
}