java多线程与同步问题

java 多线程和同步

java 多线程

多线程的作用
  1. 提高资源的利用率
    如果当执行单线程的程序时,程序发生阻塞情况,此时的CPU会处于空闲状态;而多线程中,当有一个线程发生阻塞时,CPU会执行其他的进程,从而提高了资源的利用率。
  2. 简化编程
    如果编写一个读取和操作文件的程序时,必须跟踪每个文件的读取和处理状态,相反我们可以创建两个线程,每个线程只读取或处理单个文件,这样不仅可以提高磁盘的利用率,还容编写。、
创建自定义线程的两种方式
  1. 自定义线程类,继承Thread类,重写run方法
    创建自定义线程对象,直接调用start方法,开启线程
class MyThread1 extends Thread {
	@Override
	public void run() {
		for (int i = 0; i < 100; i++) {
			System.out.println("继承Thread类自定义线程类");
		}
	}
}
//在main方法中
MyThread1 myThread1 = new MyThread1();
myThread1.start();
  1. 自定义线程类,遵从Runnable接口
    使用自定义遵从接口Runnable实现类对象,作为Thread构造方法参数,借助于Thread类对象和start方法,开启线程
class MyThread2 implements Runnable {
	@Override
	public void run() {
		for (int i = 0; i < 100; i++) {
			System.out.println("遵从Runnable接口实现自定义线程类");
		}
	}
}
//在main方法中
Thread thread = new Thread(new MyThread2());
// 借助于Thread类内的start方法开启线程
thread.start();
Thread 中的方法
构造方法名 作用
Thread() 无目标,无指定名字
Thread(Runnable target); 创建线程对象的过程中,使用Runnable接口的实现类
Thread(String name); 无目标,有名字
Thread(Runnable target, String name); 使用Runnable接口实现类对象,作为执行目标,并且指定name作为线程名
成员方法 作用
void setName(String name);String getName(); name的getter 和 Setter 方法
void setPriority(int Priority); 设置线程的优先级 [1 ~ 10]
int getPriority(); 获取线程优先级
void start(); 启动线程对象
public static void sleep(int ms); 对应进程进行休眠操作。单位毫秒
public static Thread currentThread(); 获取当前所处代码块对应的线程对象

线程安全问题和解决方案

举例来说,一个电影有100张票,有3个出售平台,实现这个案例

class SingleThread implements Runnable {
	private static int ticket = 100;
	@Override
 	public void run() {
 		while (true) {
 		// a
			if (ticket > 0) {
				System.out.println(Thread.currentThread().getName() + "售出了" + ticket + "张票");
				ticket -= 1;
				try {
				     Thread.sleep(100);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			} else {
				System.out.println(Thread.currentThread().getName() + "售罄!");
				break;
			}
		//b
		}
 	}
}
//在main方法中
Thread thread1 = new Thread(new SingleThread(), "淘票票");
Thread thread2 = new Thread(new SingleThread(), "猫眼");
Thread thread3 = new Thread(new SingleThread(), "美团");

thread1.start();
thread2.start();
thread3.start();

但是在运行的结果中,我们会发现同一张票被出售了不止一次,为了解决这种问题,我们引入了“锁”机制。

synchronized
while (true) {
	synchronized("锁") {
		//此处是上面的ab范围内的代码
	}
}

通过这种方式我们可以解决上面出现的问题

三种加锁的方式
  1. 同步方法由static修饰,所以在main方法中可以使用多个目标
    在这里插入图片描述
//main方法中
Thread thread1 = new Thread(new SingleThread3(), "淘票票");
Thread thread2 = new Thread(new SingleThread3(), "猫眼");
Thread thread3 = new Thread(new SingleThread3(), "美图");

thread1.start();
thread2.start();
thread3.start();
  1. 同步方法是非静态成员方法时,这个时候只能使用单目标

在这里插入图片描述

// main方法中
SingleThread2 singleThread2 = new SingleThread2();

Thread thread1 = new Thread(singleThread2, "淘票票");
Thread thread2 = new Thread(singleThread2, "猫眼");
Thread thread3 = new Thread(singleThread2, "美图");

thread1.start();
thread2.start();
thread3.start();
  1. Lock 锁
private static int ticket = 100;
//定义一个成员变量
static Lock lock = new ReentrantLock();
@Override
public void run() {
	while (true) {
		//在 a 的位置添加
		lock.lock();
		/*
		* ab之间的代码
		*/
		lock.unlock();
	}
}
发布了13 篇原创文章 · 获赞 17 · 访问量 3963

猜你喜欢

转载自blog.csdn.net/weixin_43932553/article/details/104617904