一个进程调用多个线程
package com.company;
import java.awt.desktop.SystemEventListener;
public class threadtest extends Thread {
@Override
public void run() {
System.out.println("yazoefan ");
}
public static void main(String[] args) {
threadtest threadtest = new threadtest();
threadtest.start();
System.out.println("yazoefan2 ");
}
}
线程开启不一定立即执行,由CPU调度执行。
要调用start方法,不能调用run方法。
继承Thread类
子类继承Thread类具备多线程能力
启动线程:子类对象.start()
不建议使用:避免oop单继承局限性
public class threadtest extends Thread {
@Override
public void run() {
System.out.println("yazoefan ");
}
public static void main(String[] args) {
threadtest threadtest = new threadtest();
threadtest.start();
System.out.println("yazoefan ");
}
}
实现Runnable接口
实现接口Runnable具有多线程能力
启动线程:传入目标对象+Thread对象.start()
推荐使用:避免单继承局限性,灵活方便,方便同一个对象被多个线程使用
public class threadtest implements Runnable{
public void run() {
System.out.println("yazoefan ");
}
public static void main(String[] args) {
threadtest threadtest = new threadtest();
new Thread(threadtest).start();
System.out.println("yazoefan2 ");
}
}
//Lambda表达式
1、当代码行只有一行时,可以去掉花括号,但是有多行的话要加上花括号
2、前提是接口为函数式接口,指接口内只有一个方法
3、多个参数也可以去掉参数类型,要去掉都去掉,必须加上括号。
public class lamdaTest {
public static void main(String[] args) {
love loveyou = () ->{
System.out.println(“fuck you 颂长”);
};
loveyou.loveyou();
}
}
interface love{
void loveyou();
}
线程状态
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IBNFdfTd-1607159694391)(:storage\vq5uykitnk5a5rk9.png)]
//线程停止
public class ThreadStop implements Runnable {
private boolean flag =true;
@Override
public void run() {
int i = 0;
while (flag){
System.out.println("fuck you"+i++);
}
}
public void stop(){
this.flag = false;
}
public static void main(String[] args) {
ThreadStop threadStop = new ThreadStop();
new Thread(threadStop).start();
for (int i = 0; i < 1000; i++) {
System.out.println("f"+i);
if (i > 900){
threadStop.stop();
break;
}
}
}
}
//线程礼让
//让线程从运行状态变成就绪状态,让CPU重新调度
public class ThreadYield implements Runnable {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"start");
Thread.yield();
System.out.println(Thread.currentThread().getName()+"stop");
}
public static void main(String[] args) {
ThreadYield threadYield = new ThreadYield();
new Thread(threadYield,"a").start();
new Thread(threadYield,"b").start();
}
}
//线程强制执行
//类似于插队,让其他线程阻塞
public class ThreadJoin implements Runnable {
@Override
public void run() {
for (int i = 0; i < 500; i++) {
System.out.println(“I’m VIP”);
}
}
public static void main(String[] args) throws InterruptedException {
ThreadJoin threadJoin = new ThreadJoin();
Thread thread = new Thread(threadJoin);
thread.start();
for (int i = 0; i < 500; i++) {
if (i == 50){
thread.join();
}
System.out.println(i);
}
}
}
//线程优先级
线程的优先级范围为1~10
数字越大优先级越高
优先级的设置最好是在start()调度前
public class ThreadPropotiy {
public static void main(String[] args) {
System.out.println(Thread.currentThread().getName()+"–>"+Thread.currentThread().getPriority());
suger suger = new suger();
Thread t1 = new Thread(suger);
Thread t2 = new Thread(suger);
Thread t3 = new Thread(suger);
Thread t4 = new Thread(suger);
Thread t5 = new Thread(suger);
t1.setPriority(10);
t1.start();
t2.setPriority(2);
t2.start();
t3.setPriority(3);
t3.start();
t4.setPriority(4);
t4.start();
t5.setPriority(5);
t5.start();
}
}
class suger implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"-->"+Thread.currentThread().getPriority());
}
}
//守护线程
线程分为用户线程和守护线程
虚拟机必须确保用户线程执行完毕
虚拟机不用等待守护线程执行完毕
public class ThreadPropotiy {
public static void main(String[] args) {
System.out.println(Thread.currentThread().getName()+"–>"+Thread.currentThread().getPriority());
suger suger = new suger();
Thread t1 = new Thread(suger);
Thread t2 = new Thread(suger);
Thread t3 = new Thread(suger);
Thread t4 = new Thread(suger);
Thread t5 = new Thread(suger);
t1.setPriority(10);
t1.start();
t2.setPriority(2);
t2.start();
t3.setPriority(3);
t3.start();
t4.setPriority(4);
t4.start();
t5.setPriority(5);
t5.start();
}
}
class suger implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"-->"+Thread.currentThread().getPriority());
}
}
//死锁
产生死锁的四个必要条件
1、互斥条件:一个资源每次只能被一个进程使用。
2、请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
3、不剥夺条件:进程已获得的资源,在未使用完成之前,不能强行剥夺。
4、循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
public class deadlock {
public static void main(String[] args) {
Makeup makeup1 = new Makeup(0,“yao”);
Makeup makeup2 = new Makeup(1,“zheng”);
new Thread(makeup1).start();
new Thread(makeup2).start();
}
}
class Lipstick{
}
class Mirror{
}
class Makeup extends Thread {
static Lipstick lipstick = new Lipstick();
static Mirror mirror = new Mirror();
int choice;
String girlname;
Makeup(int choice,String girlname) {
this.choice = choice;
this.girlname = girlname;
}
@Override
public void run() {
try {
makeup();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void makeup() throws InterruptedException {
if (choice == 0){
synchronized (lipstick){
System.out.println("lipstick");
Thread.sleep(1000);
synchronized (mirror){
System.out.println("mirror");
}
}
}else{
synchronized (mirror){
System.out.println("mirror");
Thread.sleep(2000);
synchronized (lipstick){
System.out.println("lipstick");
}
}
}
}
}
破坏死锁的方法:只要想办法破坏其中的任意一个或多个条件就能避免死锁发送。
lock锁
public class locktest {
public static void main(String[] args) {
TestLock locktest = new TestLock();
new Thread(locktest).start();
new Thread(locktest).start();
new Thread(locktest).start();
}
}
class TestLock implements Runnable{
int ticketNum = 10;
private final ReentrantLock lock = new ReentrantLock();
@Override
public void run() {
while (true){
lock.lock();
try{
if (ticketNum > 0){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(ticketNum–);
}else {
break;
}
}finally {
lock.unlock();
}
}
}
}
synchronized与Lock的对比
1、Lock是显示锁(手动开启和关闭锁,需要注意关锁)synchronized是隐式锁,除了作用于自动释放
2、Lock只有代码块锁,synchronized有代码块锁和方法锁
3、使用Lock锁,JVM将花费较少的时间来调度线程,性能更好,并且具有更好的扩展性(提供更多的子类)
有限使用顺序:
Lock > 同步代码块(已经进入了方法体,分配了相应资源) >同步方法(在方法体之外)
//管程法
//生产者消费者问题
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++) {
System.out.println("生产了"+i+"只鸡");
try {
container.push(new Chicken(i));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
//消费者
class Consumer extends Thread {
SynContainer container;
public Consumer(SynContainer container){
this.container = container;
}
//消费
@Override
public void run() {
for (int i = 0; i < 100; i++) {
try {
System.out.println(“消费了—”+container.pop().id+“只鸡”);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
//产品
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) throws InterruptedException {
//容器满了,等待消费者消费
if(count == chickens.length){
this.wait();
}
//没有满,就丢入产品
chickens[count] = chicken;
count++;
//可以通知消费者消费了
this.notifyAll();
}
//消费者消费产品
public synchronized Chicken pop() throws InterruptedException {
//判断能否消费
if (count == 0){
//等待生产者生产
this.wait();
}
count--;
Chicken chicken = chickens[count];
this.notifyAll();
return chicken;
}
}
//信号灯法
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;
}
}
//线程池
思路:提前创建多个线程,放入线程池中,使用时直接获取,使用完放回池中。可以避免频繁创建销毁,实现重复利用。
好处:
提高响应速度(减少了创建新线程的时间)
降低资源消耗(重复利用线程池中的线程,不需要每次都创建)
public class TestPool {
public static void main(String[] args) {
//创建服务,创建线程池子
//newFixedThreadPool:参数为:线程池大小
ExecutorService service = Executors.newFixedThreadPool(10);
service.execute(new MyThread());
service.execute(new MyThread());
service.execute(new MyThread());
service.execute(new MyThread());
//关闭连接
service.shutdown();
}
}
class MyThread implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}