第七章 多线程
Posted caochenlei
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第七章 多线程相关的知识,希望对你有一定的参考价值。
7.1、概述
进程:是正在运行的程序
线程:是进程中的单个顺序控制流,是一条执行路径
7.2、实现方式
7.2.1、方式一
class MyThread extends Thread {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(getName() + ":" + i);
}
}
}
public class Main {
public static void main(String[] args) {
MyThread my1 = new MyThread();
MyThread my2 = new MyThread();
my1.setName("线程一");
my2.setName("线程二");
my1.start();
my2.start();
}
}
7.2.2、方式二
class MyRunnable implements Runnable {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}
}
public class Main {
public static void main(String[] args) {
MyRunnable my = new MyRunnable();
Thread t1 = new Thread(my, "线程一");
Thread t2 = new Thread(my, "线程二");
t1.start();
t2.start();
}
}
7.3、线程优先级
class ThreadPriority extends Thread {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(getName() + ":" + i);
}
}
}
public class Main {
public static void main(String[] args) {
ThreadPriority tp1 = new ThreadPriority();
ThreadPriority tp2 = new ThreadPriority();
ThreadPriority tp3 = new ThreadPriority();
// 设置线程的名称
tp1.setName("高铁");
tp2.setName("飞机");
tp3.setName("汽车");
// 返回线程优先级
System.out.println(tp1.getPriority());
System.out.println(tp2.getPriority());
System.out.println(tp3.getPriority());
// 设置线程优先级
tp1.setPriority(5);
tp2.setPriority(10);
tp3.setPriority(1);
// 启动所有的线程
tp1.start();
tp2.start();
tp3.start();
}
}
7.4、线程的控制
sleep演示:使当前正在执行的线程停留(暂停执行)指定的毫秒数
class ThreadSleep extends Thread {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(getName() + ":" + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Main {
public static void main(String[] args) {
ThreadSleep ts1 = new ThreadSleep();
ThreadSleep ts2 = new ThreadSleep();
ThreadSleep ts3 = new ThreadSleep();
ts1.setName("曹操");
ts2.setName("刘备");
ts3.setName("孙权");
ts1.start();
ts2.start();
ts3.start();
}
}
join演示:等待这个线程死亡才能执行其它线程
class ThreadJoin extends Thread {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(getName() + ":" + i);
}
}
}
public class Main {
public static void main(String[] args) {
ThreadJoin tj1 = new ThreadJoin();
ThreadJoin tj2 = new ThreadJoin();
ThreadJoin tj3 = new ThreadJoin();
tj1.setName("曹操");
tj2.setName("刘备");
tj3.setName("孙权");
tj1.start();
try {
tj1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
tj2.start();
tj3.start();
}
}
Daemon演示:将此线程标记为守护线程,当运行的线程都是守护线程时,Java虚拟机将退出
class ThreadDaemon extends Thread {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(getName() + ":" + i);
}
}
}
public class Main {
public static void main(String[] args) {
ThreadDaemon td1 = new ThreadDaemon();
ThreadDaemon td2 = new ThreadDaemon();
td1.setName("关羽");
td2.setName("张飞");
// 设置主线程为刘备
Thread.currentThread().setName("刘备");
// 设置守护线程
td1.setDaemon(true);
td2.setDaemon(true);
// 启动守护线程
td1.start();
td2.start();
// 执行主线程的逻辑
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}
}
7.5、线程的生命周期
7.6、解决多线程数据安全问题
7.6.1、同步代码块
class SellTicket implements Runnable {
private int tickets = 100;
private Object obj = new Object();
@Override
public void run() {
while (true) {
synchronized (obj) {
if (tickets > 0) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "张票");
tickets--;
}
}
}
}
}
public class Main {
public static void main(String[] args) {
SellTicket st = new SellTicket();
Thread t1 = new Thread(st, "窗口1");
Thread t2 = new Thread(st, "窗口2");
Thread t3 = new Thread(st, "窗口3");
t1.start();
t2.start();
t3.start();
}
}
7.6.2、普通同步方法
class SellTicket implements Runnable {
private int tickets = 100;
@Override
public void run() {
while (true) {
sellTicket();
}
}
private synchronized void sellTicket() {
if (tickets > 0) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "张票");
tickets--;
}
}
}
public class Main {
public static void main(String[] args) {
SellTicket st = new SellTicket();
Thread t1 = new Thread(st, "窗口1");
Thread t2 = new Thread(st, "窗口2");
Thread t3 = new Thread(st, "窗口3");
t1.start();
t2.start();
t3.start();
}
}
7.6.3、静态同步方法
class SellTicket implements Runnable {
private static int tickets = 100;
@Override
public void run() {
while (true) {
sellTicket();
}
}
private static synchronized void sellTicket() {
if (tickets > 0) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "张票");
tickets--;
}
}
}
public class Main {
public static void main(String[] args) {
SellTicket st = new SellTicket();
Thread t1 = new Thread(st, "窗口1");
Thread t2 = new Thread(st, "窗口2");
Thread t3 = new Thread(st, "窗口3");
t1.start();
t2.start();
t3.start();
}
}
7.6.4、Look锁
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class SellTicket implements Runnable {
private int tickets = 100;
private Lock lock = new ReentrantLock();
@Override
public void run() {
while (true) {
try {
// 获得锁
lock.lock();
if (tickets > 0) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "张票");
tickets--;
}
} finally {
// 释放锁
lock.unlock();
}
}
}
}
public class Main {
public static void main(String[] args) {
SellTicket st = new SellTicket();
Thread t1 = new Thread(st, "窗口1");
Thread t2 = new Thread(st, "窗口2");
Thread t3 = new Thread(st, "窗口3");
t1.start();
t2.start();
t3.start();
}
}
7.7、生产者和消费者模式
概述:生产者消费者模式是一个十分经典的多线程协作的模式,弄懂生产者消费者问题能够让我们对多线程编程的理解更加深刻。
演示:
class Box {
// 定义一个成员变量,表示第几瓶牛奶
private int milk;
// 定义一个成员变量,表示奶箱的状态
private boolean state = false;
// 存储牛奶
public synchronized void put(int milk) {
// 如果有牛奶,等待消费
if (state) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 如果没有牛奶,就生产牛奶
this.milk = milk;
System.out.println("送奶工送第" + this.milk + "瓶奶");
// 生产完毕之后,修改奶箱状态
state = true;
// 唤醒其它等待的线程
notifyAll();
}
// 获取牛奶
public synchronized void get() {
// 如果没有牛奶,等待生产
if (!state) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 如果有牛奶,就消费牛奶
System.out.println("用户拿到第" + this.milk + "瓶奶");
// 消费完毕之后,修改奶箱状态
state = false;
// 唤醒其它等待的线程
notifyAll();
}
}
// 生产者
class Producer implements Runnable {
private Box b;
public Producer(Box b) {
this.b = b;
}
@Override
public void run() {
for (int i = 1; i <= 5; i++) {
b.put(i);
}
}
}
// 消费者
class Customer implements Runnable {
private Box b;
public Customer(Box b) {
this.b = b;
}
@Override
public void run() {
while (true) {
b.get();
}
}
}
public class Main {
public static void main(String[] args) {
Box b = new Box();
Producer p = new Producer(b);
Customer c = new Customer(b);
Thread t1 = new Thread(p);
Thread t2 = new Thread(c);
t1.start();
t2.start();
}
}
以上是关于第七章 多线程的主要内容,如果未能解决你的问题,请参考以下文章