1、实现多线程
1.1、进程
1.2、线程
1.3、多线程的第一种实现方式(第二种实现方式是1.8)
//测试类
public class Main {
public static void main(String[] args){
MyThread mt1 = new MyThread();
MyThread mt2 = new MyThread();
mt1.start();
mt2.start();
}
}
//MyThread类
public class MyThread extends Thread {
@Override
public void run() {
for(int i=0;i<100;i++){
System.out.println(i);
}
}
}
1.4、设置和获取线程名称
用set/get方法设置和获取线程名称
//测试类
public class Main {
public static void main(String[] args){
MyThread mt1 = new MyThread();
MyThread mt2 = new MyThread();
mt1.setName("飞机");
mt2.setName("高铁");
mt1.start();
mt2.start();
}
}
//MyThread类
public 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 mt1 = new MyThread("飞机");
MyThread mt2 = new MyThread("高铁");
mt1.start();
mt2.start();
}
}
//MyThread类
public class MyThread extends Thread {
public MyThread() {
}
public MyThread(String name) {
super(name);
}
@Override
public void run() {
for(int i=0;i<100;i++){
System.out.println(getName()+":"+i);
}
}
}
获取main( )方法所在的线程名称
System.out.println(Thread.currentThread().getName()); //main
1.5、线程调度
java中的优先级
System.out.println(Thread.MAX_PRIORITY); //最高优先级是:10
System.out.println(Thread.MIN_PRIORITY); //最低优先级是:1
System.out.println(Thread.NORM_PRIORITY); //默认优先级是:5
设置和返回优先级的方法
//测试类
public class Main {
public static void main(String[] args){
MyThread mt1 = new MyThread("飞机");
MyThread mt2 = new MyThread("高铁");
MyThread mt3 = new MyThread("汽车");
mt1.setPriority(10);
mt2.setPriority(5);
mt3.setPriority(1);
mt1.start();
mt2.start();
mt3.start();
// System.out.println(mt1.getPriority()); //10
// System.out.println(mt2.getPriority()); //5
// System.out.println(mt3.getPriority()); //1
}
}
MyThread类
public class MyThread extends Thread {
public MyThread() {
}
public MyThread(String name) {
super(name);
}
@Override
public void run() {
for(int i=0;i<100;i++){
System.out.println(getName()+":"+i);
}
}
}
1.6线程控制
sleep( )方法
//测试类
public class Main {
public static void main(String[] args){
MyThread mt1 = new MyThread("飞机");
MyThread mt2 = new MyThread("高铁");
MyThread mt3 = new MyThread("汽车");
mt1.start();
mt2.start();
mt3.start();
}
}
//MyThread类
public class MyThread extends Thread {
public MyThread() {
}
public MyThread(String name) {
super(name);
}
@Override
public void run() {
for(int i=0;i<100;i++){
System.out.println(getName()+":"+i);
try {
sleep(1000); //1000ms
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
join方法
//测试类
public class Main {
public static void main(String[] args) {
MyThread mt1 = new MyThread("康熙");
MyThread mt2 = new MyThread("四阿哥");
MyThread mt3 = new MyThread("八阿哥");
mt1.start();
try {
mt1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
mt2.start();
mt3.start();
}
}
//MyThread类
public class MyThread extends Thread {
public MyThread() {
}
public MyThread(String name) {
super(name);
}
@Override
public void run() {
for(int i=0;i<100;i++){
System.out.println(getName()+":"+i);
}
}
}
setDaemon( )方法
//测试类
public class Main {
public static void main(String[] args) {
MyThread mt1 = new MyThread("关羽");
MyThread mt2 = new MyThread("张飞");
//设置主线程为刘备
Thread.currentThread().setName("刘备");
//设置守护线程
mt1.setDaemon(true);
mt2.setDaemon(true);
mt1.start();
mt2.start();
for(int i=0;i<10;i++){
System.out.println(Thread.currentThread().getName()+":"+i);
}
}
}
//MyThread类
public class MyThread extends Thread {
public MyThread() {
}
public MyThread(String name) {
super(name);
}
@Override
public void run() {
for(int i=0;i<100;i++){
System.out.println(getName()+":"+i);
}
}
}
1.7、线程的生命周期
1.8、多线程的第二种实现方式(第一种实现方式是1.3)
//测试类
public class Main {
public static void main(String[] args){
//创建MyRunnable类的对象
MyRunnable mr = new MyRunnable();
//创建Thread对象,并把MyRunnable作为构造方法的参数传进去
// Thread t1 = new Thread(mr);
// Thread t2 = new Thread(mr);
//创建Thread对象,并把MyRunnable作为构造方法的参数传进去,并为线程命名
Thread t1 = new Thread(mr,"飞机");
Thread t2 = new Thread(mr,"高铁");
//启动线程
t1.start();
t2.start();
}
}
//MyRunnable类
public class MyRunnable implements Runnable{
@Override
public void run() {
for(int i=0;i<100;i++){
System.out.println(Thread.currentThread().getName()+":"+i);
}
}
}
2、线程同步
案例:卖票
//测试类
public class Main {
public static void main(String[] args){
//创建MyRunnable类的对象
MyRunnable mr = new MyRunnable();
//创建Thread对象,并把MyRunnable作为构造方法的参数传进去,并为线程命名
Thread t1 = new Thread(mr,"窗口一");
Thread t2 = new Thread(mr,"窗口二");
Thread t3 = new Thread(mr,"窗口三");
//启动线程
t1.start();
t2.start();
t3.start();
}
}
//MyRunnable类
public class MyRunnable implements Runnable{
private int tickets = 100;
@Override
public void run() {
while (true) {
if(tickets > 0){
System.out.println(Thread.currentThread().getName()+"正在卖第"+tickets+"张票");
tickets --;
}
}
}
}
2.1、卖票案例的思考
2.2、卖票问题的解决
2.3、同步代码块
//测试类
public class Main {
public static void main(String[] args){
//创建MyRunnable类的对象
MyRunnable mr = new MyRunnable();
//创建Thread对象,并把MyRunnable作为构造方法的参数传进去,并为线程命名
Thread t1 = new Thread(mr,"窗口一");
Thread t2 = new Thread(mr,"窗口二");
Thread t3 = new Thread(mr,"窗口三");
//启动线程
t1.start();
t2.start();
t3.start();
}
}
//MyRunnable类
public class MyRunnable implements Runnable{
private int tickets = 100;
private Object obj = new Object();
@Override
public void run() {
while (true) {
synchronized (obj) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (tickets > 0) {
System.out.println(Thread.currentThread().getName() + "正在卖第" + tickets + "张票");
tickets--;
}
}
}
}
}
2.4、同步方法
//测试类
public class Main {
public static void main(String[] args){
//创建MyRunnable类的对象
MyRunnable mr = new MyRunnable();
//创建Thread对象,并把MyRunnable作为构造方法的参数传进去,并为线程命名
Thread t1 = new Thread(mr,"窗口一");
Thread t2 = new Thread(mr,"窗口二");
Thread t3 = new Thread(mr,"窗口三");
//启动线程
t1.start();
t2.start();
t3.start();
}
}
//同步方法:
//MyRunnable类
public class MyRunnable implements Runnable{
private int tickets = 100;
private int i = 0;
private Object obj = new Object();
@Override
public void run() {
while (true) {
if (i % 2 == 0) {
synchronized (this) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (tickets > 0) {
System.out.println(Thread.currentThread().getName() + "正在卖第" + tickets + "张票");
tickets--;
}
}
}else {
lock();
}
i ++;
}
}
private synchronized void lock() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (tickets > 0) {
System.out.println(Thread.currentThread().getName() + "正在卖第" + tickets + "张票");
tickets--;
}
}
}
//同步静态方法:
//MyRunnable类
public class MyRunnable implements Runnable{
private static int tickets = 100;
private int i = 0;
private Object obj = new Object();
@Override
public void run() {
while (true) {
if (i % 2 == 0) {
synchronized (MyRunnable.class) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (tickets > 0) {
System.out.println(Thread.currentThread().getName() + "正在卖第" + tickets + "张票");
tickets--;
}
}
}else {
lock();
}
i ++;
}
}
private static synchronized void lock() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (tickets > 0) {
System.out.println(Thread.currentThread().getName() + "正在卖第" + tickets + "张票");
tickets--;
}
}
}
2.5、线程安全的类
// 创建线程安全类的对象
//返回指定list、map、set支持的同步(线程安全) list、map、set
List<String> list = Collections.synchronizedList(new ArrayList<>());
Map<String,String> map = Collections.synchronizedMap(new HashMap<>());
Set<String> set = Collections.synchronizedSet(new HashSet<>());
2.6、Lock锁
//测试类
import java.util.*;
public class Main {
public static void main(String[] args){
//创建MyRunnable类的对象
MyRunnable mr = new MyRunnable();
//创建Thread对象,并把MyRunnable作为构造方法的参数传进去,并为线程命名
Thread t1 = new Thread(mr,"窗口一");
Thread t2 = new Thread(mr,"窗口二");
Thread t3 = new Thread(mr,"窗口三");
//启动线程
t1.start();
t2.start();
t3.start();
}
}
//MyRunnable类
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class MyRunnable 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();
}
}
}
}
3、生产者与消费者
3.1、生产者消费者模式概述
生产者消费者案例:
//测试类
import java.util.*;
public class Main {
public static void main(String[] args){
Box b = new Box();
Produce p = new Produce(b);
Consumer c = new Consumer(b);
Thread t1 = new Thread(p);
Thread t2 = new Thread(c);
t1.start();
t2.start();
}
}
//Produce类
public class Produce implements Runnable {
private Box b;
public Produce(Box b) {
this.b = b;
}
@Override
public void run() {
for(int i=1;i<=5;i++){
b.put(i);
}
}
}
//Consumer类
public class Consumer implements Runnable{
private Box b;
public Consumer(Box b) {
this.b = b;
}
@Override
public void run() {
while (true) {
b.get();
}
}
}
//Box类
public 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();
}
}