创建线程
创建方法:
- 继承Thread类
- 实现Runnable接口
- 实现Callable接口
继承Thread类
- 继承Thread类
- 重写run方法
- 调用start方法开启线程
// 创建线程方式一:1.继承Thread类,2.重写run方法,3.调用start方法开启线程
public class ThreadTest extends Thread{
// 2.
@Override
public void run() {
// run方法线程体
for (int i = 0; i < 20; i++) {
System.out.println("run>>>");
}
}
public static void main(String[] args) {
ThreadTest threadTest = new ThreadTest();
//3.
threadTest.start();
// main线程&主线程
for (int i = 0; i < 20; i++) {
System.out.println("main>>>");
}
}
}
实现Rannable接口
- 实现Rannable接口
- 重写run方法
- 创建线程对象,执行start方法
public class RunnableThreadTest implements Runnable{
@Override
public void run() {
for (int i = 0; i < 200; i++) {
System.out.println("run>>>");
}
}
public static void main(String[] args) {
RunnableThreadTest runnableThreadTest = new RunnableThreadTest();
Thread thread = new Thread(runnableThreadTest);
thread.start();
for (int i = 0; i < 200; i++) {
System.out.println("main>>>");
}
}
}
线程停止
// 通过标志位flag停止
public class StopTest implements Runnable{
private boolean flag = true;
@Override
public void run() {
int i = 0;
while (flag){
System.out.println("run>>>"+i++ +"次");
}
}
public void stop(){
this.flag = false;
}
public static void main(String[] args) {
StopTest stopTest = new StopTest();
new Thread(stopTest).start();
for (int i = 0; i < 1000; i++) {
System.out.println("main>>>");
if(i==900){
stopTest.stop();
System.out.println("线程停止");
}
}
}
}
sleep
yield
join
线程优先级:1-10
守护线程 : daemon
// 守护daemon进程
public class DaemonTest{
public static void main(String[] args) {
// 上帝
God god = new God();
// 我
I me = new I();
Thread thread = new Thread(god);
thread.setDaemon(true);
/*
* 总结: 原本“上帝”进程会进入死循环,而setDaemon(true) > 守护线程
* 只要用户线程停止,守护线程也随之停止
* */
thread.start();
new Thread(me).start();
}
}
class I implements Runnable{
@Override
public void run() {
for (int i = 0; i < 36500; i++) {
System.out.println("每天都开心,今天是"+i+"天");
}
System.out.println("=====Goodbye,world=====");
}
}
class God implements Runnable{
@Override
public void run() {
while (true){
System.out.println("上帝守护着我");
}
}
}
并发问题
多线程对同一资源同时访问,得到相同的结果;
并发不安全案例
public class UnsafeBuyTicket {
public static void main(String[] args) {
BuyTicket buyTicket = new BuyTicket();
new Thread(buyTicket, "邓聪").start();
new Thread(buyTicket,"徐悦祺").start();
new Thread(buyTicket,"王凡").start();
}
}
class BuyTicket implements Runnable{
// 电影票初始数量
private int ticketNums = 10;
boolean flag = true; // 标志位
@Override
public void run() {
while (flag){
try {
buy();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void buy() throws InterruptedException {
//判断是否有票
if (ticketNums <= 0){
flag = false;
return;
}
Thread.sleep(100);
System.out.println(Thread.currentThread().getName()+"【购票成功】"+",票号:"+ticketNums--);
}
}
synchronized
同步方法
public synchronized void buy() throws InterruptedException {
//判断是否有票
if (ticketNums <= 0){
flag = false;
return;
}
Thread.sleep(100);
System.out.println(Thread.currentThread().getName()+"【购票成功】"+",票号:"+ticketNums--);
}
同步块
@Override
public void run() {
// 判断有没有钱
synchronized (account){
if(account.money < drawingMoney){
System.out.println(Thread.currentThread().getName()+"的账户余额不足,请及时充值");
return;
}
// 扣钱
account.money = account.money - drawingMoney;
// 得钱
nowMoney = nowMoney + drawingMoney;
System.out.println(account.name+"充值成功,余额为"+account.money);
System.out.println(this.getName()+"余额宝账户余额:"+nowMoney);
}
}
死锁
示例:
if (choice == 0){
synchronized (lipstick){
System.out.println(this.girl+"获得口红的锁");
Thread.sleep(1000);
synchronized (mirror){
System.out.println(this.girl+"获得镜子的锁");
}
}
}else {
synchronized (mirror){
System.out.println(this.girl+"获得镜子的锁");
Thread.sleep(2000);
synchronized (lipstick){
System.out.println(this.girl+"获得口红的锁");
}
}
}
Lock 锁
private final ReentrantLock lock = new ReentrantLock();
try{
// 加锁
lock.lock();
if (ticketNum > 0){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"抢票成功,票号:"+ticketNum--);
}else {
break;
}
}finally {
// 解锁
lock.unlock();
}
管程法
// 测试生产者消费者模式-利用缓冲区解决:管程法
public class TestPC {
public static void main(String[] args) {
SynContainer container = new SynContainer();
new Productor(container).start();
new Consumer(container).start();
}
}
// 生产者
class Productor extends Thread {
SynContainer container;
public Productor(SynContainer container){
this.container = container;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
container.push(new Chicken(i));
System.out.println("生产了第"+i+"只鸡");
}
}
}
// 消费者
class Consumer extends Thread {
SynContainer container;
public Consumer(SynContainer container){
this.container = container;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("消费了第"+container.pop().id+"只鸡");
}
}
}
// 产品
class Chicken {
int id;
public Chicken(int id) {
this.id = id;
}
}
// 缓冲区
class SynContainer {
// 产品
Chicken[] chickens = new Chicken[10];
// 容器计数器
int count = 0;
public synchronized void push(Chicken chicken) {
// 如果容器满了,就需要等待消费者消费
if (count == chickens.length) {
// 通知消费者消费,生产者等待
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 未满,我们需要丢入产品
chickens[count] = chicken;
count++;
// 通知消费者消费
this.notifyAll();
}
// 消费者消费产品
public synchronized Chicken pop(){
// 当容器为0,等待生产者生产
if (count == 0){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 消费
count--;
Chicken chicken = chickens[count];
// 通知生产者生产
this.notifyAll();
return chicken;
}
// wait notify count(容器)
}
信号灯法
public class TestPC2 {
public static void main(String[] args) {
TV tv = new TV();
new Player(tv).start();
new Watcher(tv).start();
}
}
// 生产者:演员
class Player extends Thread {
TV tv;
public Player(TV tv){
this.tv = tv;
}
@Override
public void run() {
for (int i = 0; i < 20; i++) {
if (i % 2 == 0){
this.tv.play("快乐大本营播放中");
}else {
this.tv.play("抖音:记录美好生活");
}
}
}
}
// 消费者:观众
class Watcher extends Thread {
TV tv;
public Watcher(TV tv){
this.tv = tv;
}
@Override
public void run() {
for (int i = 0; i < 20; i++) {
tv.watch();
}
}
}
class TV {
String voice;
boolean flag = true;
// 表演
public synchronized void play(String voice) {
if (!flag){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("演员表演了" + voice);
// 通知观众看
this.notifyAll();
this.voice = voice;
this.flag = !this.flag;
}
// 观看
public synchronized void watch() {
if (flag) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("观众看了"+voice);
// 通知演员表演
this.notifyAll();
this.flag = !this.flag;
}
}
// flag wait notify