1.进程和线程的区别
进程:正在运行的程序,是系统分配资源的基本单位。
线程:是进程中的一个任务,与其他线程可以独立运行。它是cpu调度的单位。
2. Java中如何创建多线程
2.1 继承Thread类来完成多线程
public class MyThread extends Thread{
//重写run方法 当线程启动时,会调用run方法体中的代码
@Override
public void run() {
for (int i = 0; i < 20; i++) {
System.out.println("线程-=-=-=-=-="+i);
}
}
}
public class MyThreadTest {
public static void main(String[] args) throws InterruptedException {
MyThread myThread = new MyThread();
//开启线程
myThread.start();
for (int i = 0; i < 20; i++) {
System.out.println("main-=-=-=-=-="+i);
}
}
}
2.2 获取和设置线程名称
public class MyThread extends Thread{
//重写run方法 当线程启动时,会调用run方法体中的代码
@Override
public void run() {
for (int i = 0; i < 20; i++) {
//Thread.currentThread().getName() 获取线程名称
System.out.println(Thread.currentThread().getName()+"线程-=-=-=-=-="+i);
}
}
}
public class MyThreadTest {
public static void main(String[] args) throws InterruptedException {
MyThread myThread = new MyThread();
//设置线程名称
myThread.setName("线程1");
myThread.start();
for (int i = 0; i < 20; i++) {
System.out.println("main-=-=-=-=-="+i);
}
}
}
3. 实现Runnable接口
public class MyThread implements Runnable{
public void run() {
for (int i = 0; i < 20; i++) {
//Thread.currentThread().getName() 获取线程名称
System.out.println(Thread.currentThread().getName()+"线程-=-=-=-=-="+i);
}
}
}
public class MyThreadTest {
public static void main(String[] args) throws InterruptedException {
MyThread myThread = new MyThread();
Thread thread = new Thread(myThread,"线程1");
thread.start();
for (int i = 0; i < 20; i++) {
System.out.println(Thread.currentThread().getName()+"main-=-=-=-=-="+i);
}
}
}
4. Thread 线程类中常用的方法
休眠:sleep(m)
m:当前线程主动休眠毫秒
放弃:yield()
当前线程主动放弃时间片,回到就绪状态,竞争下一次时间片
加入:join()
允许其他线程加入到当前线程中,直到其他线程执行完毕后,当前线程才会执行
优先级:setPriority()
线程优先级默认为5,优先级越高,表示获取cpu概率越高
守护线程:setDaemon(true)
如果程序中所有前台线程都执行完毕,后台线程也会自动结束。垃圾回收线程属于守护线程
5. 线程安全问题
当多个线程共享一个资源时,可能会出现线程安全问题。使用锁 可以解决线程安全问题,锁定的代码都是原子操作。
第一种自动锁:synchronized
public class TickeTask implements Runnable {
private int ticke = 100;
@Override
public void run() {
while (true) {
//自动上锁 自动释放锁
synchronized (this) {
if (ticke > 0) {
ticke--;
System.out.println(Thread.currentThread().getName() + "卖了一张票还剩下" + ticke + "张");
}else {
break;
}
}
}
}
}
public class TickeTaskTest {
public static void main(String[] args) {
TickeTask tickeTask = new TickeTask();
Thread thread1 = new Thread(tickeTask,"线程1");
Thread thread2 = new Thread(tickeTask,"线程2");
Thread thread3 = new Thread(tickeTask,"线程3");
Thread thread4 = new Thread(tickeTask,"线程4");
thread1.start();
thread2.start();
thread3.start();
thread4.start();
}
}
第二种手动锁:Lock
public class TickeTask implements Runnable {
private int ticke = 100;
//创建手动锁对象
private Lock l = new ReentrantLock();
@Override
public void run() {
while (true){
//手动上锁
l.lock();
if (ticke>0){
ticke--;
System.out.println(Thread.currentThread().getName() + "卖了一张票还剩下" + ticke + "张");
}else {
break;
}
l.unlock();//释放资源
}
}
}
public class TickeTaskTest {
public static void main(String[] args) {
TickeTask tickeTask = new TickeTask();
Thread thread1 = new Thread(tickeTask,"线程1");
Thread thread2 = new Thread(tickeTask,"线程2");
Thread thread3 = new Thread(tickeTask,"线程3");
Thread thread4 = new Thread(tickeTask,"线程4");
thread1.start();
thread2.start();
thread3.start();
thread4.start();
}
}