首先讲讲多线程相关知识:
多线程是指在一个程序中同时运行多个线程,每个线程独立执行不同的任务,从而实现并行处理。在多线程编程中,程序可以同时处理多个任务,从而提高程序的执行效率和性能。
Java是一种支持多线程编程的编程语言。在Java中,你可以通过创建Thread对象或者实现Runnable接口来定义一个线程,并在其上执行任务。Java的多线程编程有以下几个重要的概念:
-
Thread类:Java中的Thread类用于创建一个新线程。你可以通过继承Thread类并重写run方法来定义线程的任务。然后,通过调用start方法来启动线程,使其执行run方法中的任务。
-
Runnable接口:Runnable接口是另一种实现线程的方式。通过实现Runnable接口并重写run方法,你可以定义线程的任务。然后,将实现了Runnable接口的对象作为参数传递给Thread类的构造函数,并通过调用start方法来启动线程。
同步与锁:那么在多线程编程中,多个线程可能会同时访问共享的数据或资源,这可能导致竞态条件和线程安全问题。为了避免这种情况,可以使用同步机制,如synchronized关键字或Lock接口,来保护共享资源,确保线程之间的安全访问。
比如:
MyThread t1=new MyThread();
MyThread t2=new MyThread();
MyThread t3=new MyThread();
t1.setName("窗口1");
t2.setName("窗口2");
t3.setName("窗口3");
t1.start();
t2.start();
t3.start();
我们创建3个线程,分别表示为窗口1,2,3,他们的具体run方法如下:
package MultiThread0726;
public class MyThread extends Thread{
static int ticket=0;
public void run()
{
while(true)
{
if(ticket<100)
{
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ticket++;
System.out.println(this.getName()+"正在卖第"+ticket+"张票");
}
else break;
}
}
}
模拟3个创窗口卖电影票,现在是不加锁的情况,我们来看一下运行情况:
可以发现多个窗口会卖同一张票,放到高并发场景下就会发生超卖现象,解决办法就是加锁:
package MultiThread0726;
public class MyThread extends Thread{
static int ticket=0;
static Object obj=new Object();
public void run()
{
while(true)
{
//同步代码块
synchronized(Thread.class)//要一把锁
{
if(ticket<100)
{
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ticket++;
System.out.println(this.getName()+"正在卖第"+ticket+"张票");
}
else break;
}
}
}
}
需要用到synchronized关键字,请注意synchronized后面括号相当于锁的对象,必须保证唯一。
synchronized关键字隐式地获取锁,并在方法或代码块执行完成后释放锁。当一个线程进入synchronized方法或代码块时,其他线程将被阻塞,直到当前线程执行完毕并释放锁。