再说线程之前我们来了解一下,什么是程序和什么是进程?
(1) 程序:可以运行的一波代码。
(2) 进程:程序的一次运行
1 线程:线程可以理解成轻量级进程。
一个进程一定会有一个主线程,主线程可能以有多个子线程。这样就构成了多线程。
2 线程之间的工作原理
线程和线程之间是采用抢占硬件资源的方式来运行。
3 线程的生命周期:
新建 就绪 运行 阻塞 死亡
![](https://i-blog.csdnimg.cn/blog_migrate/67d10578a78ebbcac8a913953b25bce1.png)
创建线程常用的两种方法
(1)继承Thread类的方式
1.写一个类继承Thread类
2.重写run方法
3.在主线程中创建该类的对象
4.调用该对象的start方法。
public class TestThread extends Thread {
@Override
public void run() {
System.out.println("我是自己创建的线程");
System.out.println(Thread.currentThread().getId());
}
}
public class MyThread {
public static void main(String[] args) {
// 创建子线程
TestThread t1 = new TestThread();
// 让线程就绪
t1.start();
// Thread.currentThread() 代表主线程 , 主线程不需要创建,运行一个主方法就自动创建
System.out.println("主线程ID " + Thread.currentThread().getId());
System.out.println("子线程ID " + t1.getId());
}
}
(2)实现Runnable接口
1.写一个类实现Runnable接口
2.重写run方法
3.在主线程中创建一个Runnable类的对象
4.创建一个Thread对象,把Runable中的对象传入。
5.调用Thread对象的start方法。
public class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("我是用接口实现的线程");
}
}
public class TestRunnable {
public static void main(String[] args) {
MyRunnable mr = new MyRunnable();
Thread t = new Thread(mr);
t.start();
}
}
![](https://i-blog.csdnimg.cn/blog_migrate/9be66e8c3fa24797bf7274a6a08e453a.png)
多线程是不安全安全的
例如 我们让两个线程同时打印1-10
// 让两个线程共同打印1-10
public class MyMain {
static int i = 1;
static String s = "ddd";
public static void main(String[] args) {
Thread t1 = new Thread(MyMain::println);
Thread t2 = new Thread(MyMain::println);
t1.setName("线程一");
t2.setName("线程二");
t1.start();
t2.start();
}
public static void println() {
for (; i < 10;) {
System.out.println(Thread.currentThread().getName() + "--" + i);
i++;
}
}
}
运行结果为,一下,所以线程不安全
(方法一)使用同步代码块的方式解决
public class MyMain {
static int i = 1;
public static void main(String[] args) {
Thread t1 = new Thread(MyMain::println);
Thread t2 = new Thread(MyMain::println);
t1.setName("线程一");
t2.setName("线程二");
t1.start();
t2.start();
}
public static void println() {
for (; i < 10;) {
//注释 synchronized 是一个锁,object是一个钥匙
synchronized (Object.class) {
System.out.println(Thread.currentThread().getName() + " " + i);
try {
// 注释 让当前线程休眠
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
i++;
}
}
}
}
结果为