基础知识
- 线程
线程是操作系统能够进行运算调度的最小单位,被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务 - 线程锁
锁定一个公共的变量在一个线程中,其它未取得的线程处于等待中,一直等到变量被线程锁释放,避免多个线程同时使用一个变量造成数据错误 - 多线程存在的机制
真正的同步执行几个线程是不存在的,由于CPU的处理速度极快,所以每个一定的时间处理一个线程的一部分,在人看起来就像是并行,而线程与线程之间是通过竞争来实现执行的,可以通过设置优先级来控制线程得到执行的机会
一、继承Thread来创建线程类
① 函数
函数作用 | 函数名 | 解释 |
---|
获取当前线程 | Thread.currentThread() | 返回当前线程 |
获取线程名 | getName() | 获取线程名 |
设置线程名 | setName(name) | 设置线程名 |
设置守护线程 | setDaemon(true/false) | 被设置守护的线程会随主线程的结束而销毁 |
启动线程 | start() | 触发线程 |
加入其他线程 | join() | 加入的线程会优先执行完再执行主线程 |
线程休眠 | Thread.sleep(time) | 暂停当前线程time时间 |
获取线程优先级 | getPriority() | 获取线程优先级 |
设置线程优先级 | setPriority() | 设置线程优先级(优先级在1到10的数字) |
获取线程组 | getThreadGroup() | 获取线程组 |
线程中断 | interrupt() | 设置线程的中断标志,需在run()中处理 |
线程中断 | interrupted() | 线程是否中断 |
线程中断 | isInterrupted() | 线程是否中断 |
② 实例
public class MyThread extends Thread{
public void run() {
for(int i = 0; i < 100; i++) {
if(interrupted()) {
break;
}
System.out.println("线程名" + getName() + ": " + i);
}
System.out.println("线程操作方法");
}
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.setName("线程");
System.out.println(thread.getName());
System.out.println(thread.getPriority());
System.out.println(Thread.MAX_PRIORITY);
System.out.println(Thread.MIN_PRIORITY);
System.out.println(Thread.NORM_PRIORITY);
thread.setPriority(5);
thread.start();
ThreadGroup thgroup = thread.getThreadGroup();
Thread th = new Thread(thgroup, "线程");
thread.setDaemon(true);
thread.interrupt();
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
Thread mainThread = Thread.currentThread();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
- 优点:创建线程对象简单
- 缺点:创建线程间的数据共享只能通过静态变量来实现
二、实现Runnable接口来创建线程类
class MyRunnable implements Runnable{
public void run() {
for(int i = 0; i < 100; i++) {
System.out.println("线程名" + Thread.currentThread().getName() + ": " + i);
}
}
public static void main(String[] args) {
MyRunnable myRunnable = new MyRunnable();
Thread thread = new Thread(myRunnable,"线程");
thread.start();
}
}
- 优点:实现的Runnable接口的类中定义的变量可以被所有线程共享
- 缺点:创建线程得通过Thread()来实现
三、三种解决线程安全的方法
- 第一种方法 —>同步锁synchronized (Object lock)
class MyRunnable implements Runnable{
private int ticketNum = 100;
private Object lock = new Object();
public void run() {
while(true) {
synchronized (lock) {
if(ticketNum > 0) {
System.out.println(Thread.currentThread().getName() + "卖出第" + ticketNum + "张票");
ticketNum--;
}
else {
break;
}
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
- 第二种方法 —>同步方法
class MyRunnable implements Runnable{
private int ticketNum = 100;
public void run() {
while(ticketNum > 0) {
saleTicket();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private synchronized void saleTicket() {
if(ticketNum > 0) {
System.out.println(Thread.currentThread().getName() + "卖出第" + ticketNum + "张票");
ticketNum--;
}
}
}
- 第三种方法 —>ReentrantLock锁
class MyRunnable implements Runnable{
private int ticketNum = 100;
private ReentrantLock lock1 = new ReentrantLock();
public void run() {
while(true) {
lock1.lock();
if(ticketNum > 0) {
System.out.println(Thread.currentThread().getName() + "卖出第" + ticketNum + "张票");
ticketNum--;
}
else {
break;
}
lock1.unlock();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
四、定时器的使用------重写TimerTask中的run()方法
class MyTimerTask extends TimerTask{
public void run() {
System.out.println("定时器");
}
public static void main(String[] args) {
Timer time = new Timer();
time.schedule(new MyTimerTask(), 2000,500);
time.cancel();
}
}