进程和线程?
进程
- 是指一个内存中运行的应用程序,每个进程都有一个独立的内存空间
线程
- 是进程中的一个执行路径,共享一个内存空间,线程之间可以自由切换,并发执行. 一个进程最少有一个线程
- 线程实际上是在进程基础之上的进一步划分,一个进程启动之后,里面的若干执行路径又可以划分成若干个线程
Java 中实现多线程
继承Thread 类创建线程类
继承Thread类之后,需要重写run()方法,并在run(){中写需要执行的代码},在使用时需要初始化类,同时调用类的start()方法。在实现Thread时,可以直接在main方法中直接new Thread(){继承方法}.start()执行。使用.setPriority()设置线程优先级。使用sleep()(静态方法,可直接调用Thread.sleep())休眠/阻塞(消耗时间的操作)线程。
public class Main {
public static void main(String[] args) {
// 创建线程
MyThead myThead = new MyThead();
// 线程开启
myThead.start();
for (int i = 0; i < 10; i++) {
System.out.println("你"+i);
}
}
static class MyThead extends Thread{
// 重写 run方法
@Override
public void run(){
for (int i = 0; i < 10; i++) {
System.out.println("我"+i);
}
}
}
}
实现截图:由于是抢占式运行,故运行结果有可能不同。
实现 Runnable 接口创建线程类
与Thread类使用方法一致,但Runnable为接口;且Runnable为任务,需要使用Thread类(线程)执行任务。
thread.interrupt():对线程进行标记,发现后,进入异常 然后开发人员对异常进行操作。
public class StopThread {
public static void main(String[] args) throws InterruptedException {
Thread thread=new Thread(new StopRunnable());
thread.start();
for (int i = 0; i <5 ; i++) {
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName()+":"+i);
}
//对线程进行标记,发现后,进入异常,提醒线程该结束了
thread.interrupt();
}
static class StopRunnable implements Runnable{
@Override
public void run() {
try {
for (int i = 0; i < 10; i++) {
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName()+"i");
}
} catch (InterruptedException e) {
System.out.println("发现标记,结束线程");
//结束线程
return;
}
}
}
}
}
实现截图:
线程休眠
线程休眠使用sleep()方法,参数设置成要休眠多久.
/*
线程休眠
*/
for (int i = 0; i < 10; i++) {
// 休眠一秒钟
Thread.sleep(1000);
System.out.println(i);
}
守护线程
当主线程死亡时,其它线程也会死亡
public static void main(String[] args) throws InterruptedException {
/*
守护线程 在主线程死亡时,其它线程也会死亡
*/
Thread thread = new Thread(new MyRunnable());
// true打开守护线程
thread.setDaemon(true);
thread.start();
for (int i = 1; i < 5; i++) {
try {
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() + ":" + i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
static class MyRunnable implements Runnable {
@Override
public void run() {
for (int i = 1; i < 10; i++) {
try {
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() + ":" + i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
线程不安全解决方案
线程不安全解决方案1.同步代码块
同步代码块属于是:隐式锁,排队执行,使用synchronized(锁对象){},锁对象必须是同一个
public class demo1 {
public static void main(String[] args) {
Runnable runnable = new MyRunnable();
new Thread(runnable).start();
new Thread(runnable).start();
new Thread(runnable).start();
System.out.println(Thread.currentThread().getName());
}
static class MyRunnable implements Runnable {
private int count = 10;
// 创建锁对象
private Object o = new Object();
@Override
public void run() {
while (count > 0) {
// 调用锁对象
synchronized (o) {
if (count == 0) {
return;
}else {
System.out.println("开始卖票!!");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
count--;
System.out.println("出票成功,余票" + count);
}
}
}
}
}
}
运行截图:
线程不安全解决方案2.同步方法
同步方法属于:隐式锁,在方法类型前加上synchronized、方法内部自动调用this调用对象,静态时必须使用类名.class,
public class demo2 {
public static void main(String[] args) {
// 创建线程
Runnable runnable = new MyRunnable();
// 同时开启三个线程
new Thread(runnable).start();
new Thread(runnable).start();
new Thread(runnable).start();
}
static class MyRunnable implements Runnable {
private int count = 10;
@Override
public void run() {
while (count > 0) {
boolean sale = sale();
if (!sale) {
break;
}
}
}
// 创建同步方法
public synchronized boolean sale() {
if (count == 0) {
return false;
} else {
System.out.println("开始卖票!!");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
count--;
System.out.println("出票成功,余票" + count);
return true;
}
}
}
运行截图
线程不安全解决方案3.Lock
Lock属于:显式锁,需要使用子类ReentrantLock,更适合面向对象
初始化锁:Lock l=new ReentrantLock();
public class demo3 {
public static void main(String[] args) {
Runnable runnable = new MyRunnable();
// 同时开启三个线程
new Thread(runnable).start();
new Thread(runnable).start();
new Thread(runnable).start();
}
static class MyRunnable implements Runnable {
private int count = 10;
// 创建Lock对象
Lock look = new ReentrantLock();
@Override
public void run() {
while (count > 0) {
// 调研lock对象
look.lock();
if (count == 0) {
return;
} else {
System.out.println("开始卖票!!");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
count--;
System.out.println("出票成功,余票" + count);
}
}
}
}
}
运行截图