多线程的创建、线程的状态和调度and同步、join和yield以及单例设计模式的种类

创建线程方式 重要

​ 继承Thead

​ 实现Runnable接口,重写run方法

package com.qfedu.thread;

/**
 * 实现Runnable接口,重写run()方法
 * @author renrui
 *
 */
public class MyRunnable implements Runnable {

	@Override
	public void run() {
		// TODO Auto-generated method stub
		for(int i = 0; i < 100; i++) {
			System.out.println(Thread.currentThread().getName() + ":" + i);
		}
	}

}

package com.qfedu.thread;

public class App {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		// 使用线程,推荐通过实现Runnable接口方式
		MyRunnable myRunnable = new MyRunnable();
		
		// 创建线程
		Thread t1 = new Thread(myRunnable);
		// 获取优先级 默认优先级5
		System.out.println(t1.getPriority());
		// 设置优先级 1-10
		// t1.setPriority(10);
		t1.setPriority(Thread.MAX_PRIORITY);
		
		Thread t2 = new Thread(myRunnable);
		// 启动线程
		t1.start();
		t2.start();
		
		// 使用匿名内部类
		Thread t3 = new Thread(new Runnable() {
			
			@Override
			public void run() {
				// TODO Auto-generated method stub
				for(int i = 0; i < 100; i++) {
					System.out.println(Thread.currentThread().getName() + ":" + i);
				}
			}
		});
		t3.start();
		
		
	}

}

java中线程的状态 重要

6状态

1)新建状态new: 调用new 创建对象

2)可运行状态runnable: 调用start(),进入可运行状态,可以认为可运行状态中包含就绪和运行两个状态

3)阻塞状态blocking:某个线程调用同步方法,还没有释放锁时,其他线程也访问该方法,进行阻塞状态。当线程执行完毕释放锁,那些阻塞的线程进入可运行状态

4)等待状态waiting:调用wait()/join()等方法后,线程进入等待状态。当join对应的线程执行完毕,或者wait()的线程被唤醒,等待的线程进入可运行状态

5)计时等待状态time waiting: 和等待状态类型,调用sleep(long)/wait(long)/join(long)等方法,进入计时等待状态

6)终止状态terminated:run方法执行完毕,或者线程异常,进入终止状态

线程的调度

sleep 线程睡眠

​ 某个线程中调用sleep方法,该线程睡眠,进入计时等待状态

package com.qfedu.sleep;

public class App {

	public static void main(String[] args) {
		// TODO Auto-generated method stub

		MyThread t = new MyThread();
		t.start();
		
		try {
			// 受检异常
			// 线程睡眠 参数表示睡眠时间 单位毫秒
			// main方法中调用sleep,主线程休眠
			Thread.sleep(10);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		for(int i = 0; i < 100; i++) {
			System.out.println(Thread.currentThread().getName() + ":" + i);
		}
		
	}

}

class MyThread extends Thread {
	
	@Override
	public void run() {
		try {
			Thread.sleep(20);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		for(int i = 0; i < 100; i++) {
			System.out.println(Thread.currentThread().getName() + ":" + i);
		}
	}
}

join 了解

​ 线程插入 A 线程中,调用B.join() B线程就会插队,B线程执行完,执行其他线程逻辑

package com.qfedu.join;

public class App {

	public static void main(String[] args) {
		// TODO Auto-generated method stub

		MyThread t = new MyThread();
		t.start();
		
		for(int i = 0; i < 500; i++) {
			
			if(i == 20) {
				try {
					// 线程插队
					// main方法中调用join方法的,main主线程进入等待状态
					// t线程插队,插队的线程执行完毕,等待的线程才会继续执行
					// t.join();
					
					// 线程插队时,指定一个时间,单位毫秒
					// 插队的线程执行完毕,或者插队时间到,等待的线程进入可运行状态
					// main和t共同竞争cpu资源
					t.join(1);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			
			System.out.println(Thread.currentThread().getName() + ":" + i);
		}
		
	}

}

class MyThread extends Thread {
	
	@Override
	public void run() {
		for(int i = 0; i < 500; i++) {
			System.out.println(Thread.currentThread().getName() + ":" + i);
		}
	}
}

yield 了解

​ 线程礼让,某个线程中调用yield方法,该线程进入就绪状态

package com.qfedu.yield;

public class App {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Product p = new Product();
		Customer c = new Customer();
		
		p.start();
		c.start();
	}

}

class Product extends Thread {
	@Override
	public void run() {
		for(int i = 0; i < 100; i++) {
			if(i == 8) {
				// 调用yield方法之前,线程之间是竞争关系
				// 线程礼让
				// 调用礼让方法的线程进入就绪状态
				// 和其他线程一起竞争cpu资源
				Thread.yield();
			}
			System.out.println(Thread.currentThread().getName() + ":" + i);
		}
	}
}

class Customer extends Thread {
	@Override
	public void run() {
		for(int i = 0; i < 100; i++) {
			System.out.println(Thread.currentThread().getName() + ":" + i);
		}
	}
}

线程同步 重要

​ 主要为了解决线程安全的问题

​ 多个线程访问线程共享的数据时 ,要注意线程安全问题

​ 课件中,使用同步机制,实现线程同步

​ 同步代码块

​ synchronized(锁对象) {}

​ 同步方法

​ synchronized 返回值 方法名(参数) {}

​ 注意:锁对象需要唯一,多个需要共享一把锁

package com.qfedu.syn;

public class App {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Ticket ticket = new Ticket();
		
		// 启动了50个线程
		for(int i = 0; i < 50; i++) {
			Thread t = new Thread(ticket);
			t.start();
		}
	}

}

class Ticket implements Runnable {
	// 初始有100张票
	// 50个线程共享num
	private int num = 100;
	
	@Override
	public void run() {
		// TODO Auto-generated method stub
//		num--;
//		System.out.println("剩余票数:" + num);
		
		// 调用同步方法
		// A线程先抢到cpu资源,执行同步方法,加锁,
		// A线程执行代码的过程中,失去cpu的控制权(调度系统将cpu分配给其他线程),B线程抢到cpu,执行同步方法
		// B执行同步方法时,A线程还没有执行完代码,锁依旧存在,B就会阻塞,等着A释放锁
		// A释放锁后,其他阻塞的线程进入就绪状态,哪个线程先抢到cpu,哪个线程就可以执行同步方法,并加锁
		
		// 注意:A执行完,释放锁,其他线程,比如BCDEF等线程,还需要抢占cpu资源,而不是B先执行
		// 阻塞的线程会在“锁池”中记录(了解)
		// show();
		
		// 同步代码块
		// 基本语法:synchronized(代表锁的对象) {执行的逻辑}
		// 50个线程共用一个ticket对象,this表示当前的ticket对象,所以this可作为多个线程公用的锁
		synchronized (this) {
		// synchronized (Ticket.class) {  // 该写法了解一下 Ticket.class表示获取Ticket的Class对象
			num--;
			System.out.println(Thread.currentThread().getName() + ",剩余票数:" + num);
		}
		
	}
	
	// 同步方法,在代码中“锁”也是对象,同步方法中,使用的锁是this对象
	public synchronized void show() {
		num--;
		System.out.println(Thread.currentThread().getName() + ",剩余票数:" + num);
	}
	
}

单例设计模式 次重要

​ 某个类,在整个程序中只能有一个对象的时候,就可以使用单例模式

懒汉式

package com.qfedu.singleton;

/**
 * 懒汉式 考虑多线程环境的线程安全问题
 * @author renrui
 *
 */
public class Singleton {
	private static Singleton singleton = null;
	
	// 构造方法设置成私有的,类外不能通过new 创建对象
	private Singleton() {}
	
	// 在类内部创建对象
	public static synchronized Singleton getInstance() {
		if(singleton == null) {
			singleton = new Singleton();
			return singleton;
		} else {
			return singleton;
		}
		
	}
}

饿汉式

package com.qfedu.singleton;

/**
 * 饿汉式 推荐
 * @author renrui
 *
 */
public class Singleton2 {
	
	// 类加载的时候创建静态变量,只会执行一次
	// 定义静态变量,直接创建对象并赋值
	private static Singleton2 singleton2 = new Singleton2();

	private Singleton2() {}
	
	public static Singleton2 getInstance() {
		return singleton2;
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值