多线程
多线程
一、进程线程的区别:
- 进程是操作系统资源分配的基本单位,线程是CPU的基本调度单位。
- 一个程序运行后至少有一个进程。
- 一个进程至少包含一个线程。
- 进程间不能共享数据段地址,但同进程的线程之间可以。
二、线程的组成:
- CPU时间片:操作系统(OS)会为每个线程分配执行时间。
- 运行数据:
- 堆空间:存储线程需使用的对象,多个线程可以共享堆中的对象。
- 栈空间:存储线程需要使用的局部变量,每个线程都拥有独立的栈。
三、线程的特点:
- 线程抢占式执行(效率高、可防止单一线程长时间独占CPU)。
- 在单核CPU中,宏观上同时执行,微观上顺序执行。
四、创建线程
- 继承Thread类,重写run方法。
- 实现Runnable接口
- 实现Callable接口
五、获取和修改线程名称
-
获取线程ID和线程名称
-
在Thread的子类中调用this.getId()或者this.getName()。只适合继承Thread类
class MyThread extends Thread{ @Override public void run() { int sum=0; for (int i=0;i<=100;i++){ //this.getId()获取线程ID,this.getName()获取线程名称 System.out.println("线程ID:"+this.getId()+"线程名称:"+this.getName()+"子线程------"+i); } } } -
使用Thread.currentThread().getId()和Thread.currentThread().getName()。可以不继承Thread类
class MyThread extends Thread{ @Override public void run() { for (int i=0;i<=100;i++){ System.out.println("线程ID:"+Thread.currentThread().getId()+"线程名称:"+Thread.currentThread().getName()+"子线程------"+i); } } }
-
-
修改线程名称
-
调用线程对象的setName()方法。
//创建线程对象 MyThread myThread = new MyThread(); MyThread myThread1 = new MyThread(); //修改线程名称 myThread.setName("QQ"); myThread1.setName("微信"); -
使用线程子类的构造方法赋值。
package com.sun.base.XianCheng; public class TestThread { public static void main(String[] args) { //创建线程对象 MyThread myThread = new MyThread("QQ"); MyThread myThread1 = new MyThread("微信"); ... /** * 线程类 */ class MyThread extends Thread{ public MyThread(){ } public MyThread(String name) { super(name); } ...
-
继承Thread类--代码实现四个窗口各卖一百张票案例
package com.sun.base.XianCheng;
public class TestThread {
public static void main(String[] args) {
//创建线程对象
MyThread myThread = new MyThread("窗口1");
MyThread myThread1 = new MyThread("窗口2");
MyThread myThread2 = new MyThread("窗口3");
MyThread myThread3 = new MyThread("窗口4");
//启动线程,不能run方法
myThread.start();
myThread1.start();
myThread2.start();
myThread3.start();
}
}
/**
* 卖票窗口类(线程类)
*/
class MyThread extends Thread{
private int ticket=100; //100张票
public MyThread(){
}
public MyThread(String name) {
super(name);
}
@Override
public void run() {
//买票功能
while (true){
if (ticket<0){
break;
}
System.out.println("线程ID:"+Thread.currentThread().getId()+"线程名称:"+Thread.currentThread().getName()+"卖了第"+(100-ticket)+"张票");
ticket--;
}
}
}
实现Runnable接口
package com.sun.base.XianCheng;
public class TextRunnable {
public static void main(String[] args) {
//匿名内部类 创建可运行对象
Runnable runnable = new Runnable() {
@Override
public void run() {
for (int i=0;i<100;i++){
System.out.println(Thread.currentThread().getName()+"----"+i);
}
}
};
//创建线程对象
Thread thread = new Thread(runnable, "我的子线程");
//启动线程
thread.start();
for (int i=0;i<50;i++){
System.out.println("主线程----"+i);
}
}
}
六、线程的方法
- 休眠(限期等待):public static void sleep(long millis) 当前线程主动休眠millis毫秒
public void run() {
for (int i=0;i<100;i++){
System.out.println(Thread.currentThread().getName()+"----"+i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
- 放弃:public static void yield() 当前线程主动放弃时间片,回到就绪状态,竞争下一次时间片
public void run() {
for (int i=0;i<100;i++){
System.out.println(Thread.currentThread().getName()+"----"+i);
//主动放弃
Thread.yield();
}
}
-
加入(无限期等待):public final void join() 允许其他线程加入到当前线程中
- 在启动线程之后,加入当前线程,并阻塞当前线程,直到加入线程执行完毕
-
优先级
- 线程对象.setPriority();在线程启动之前
- 线程优先级为1-10,默认为5,优先级越高,表示获取CPU机会越多。
-
守护线程
- 线程对象.setDaemon(true);设置为守护线程。在线程启动之前
- 线程有两类:用户线程(前台线程)、守护线程(后台线程)
- 如果程序中所有前台线程都执行完毕了,后台线程就会自动结束
- 垃圾回收器线程属于守护线程
-
线程通信
- 等待:public final void wait() / public final void wait(long timeout)
- 通知:public final void notify() / public final void notifyAll()
七、线程安全
-
同步方式
-
同步代码块 synchronized(临界资源对象){//对临界资源对象加锁
//代码(原子操作)} //每个对象都拥有一个互斥锁标记,用来分配给线程。只有拥有对象互斥锁标记的线程,才能进入对该对象加锁的同步代码块。
private Object obj =new Object(); @Override public void run() { while (true) { synchronized (obj) { if (ticket < 0) { break; } System.out.println(Thread.currentThread().getName() + "卖了第" + (100 - ticket) + "张票"); ticket--; } } } -
同步方法 synchronized 返回值类型 方法名称(形参列表){//对当前对象(this)加锁
//代码(原子操作)}
//卖票方法 public synchronized boolean sale(){//锁 this ;如果是静态方法 锁 Ticket.class if (ticket<0){ return false; } System.out.println(Thread.currentThread().getName() + "卖了第" + (100 - ticket) + "张票"); ticket--; return true; }
-

浙公网安备 33010602011771号