Java多线程创建、启动、信息共享问题
java多线程的创建、启动
java为多线程创建提供两种方案:
一:继承Thread类
二:实现Runnable接口。
说明:由于Thread类实现了Runnable接口,故而继承Thread类,本质上也是实现Runnable接口
不同:在启动方式上不一样,继承Thread类后,线程只需要调用start方法即可,实现Runnable接口需要借助Thread类进行包装后才能调用start方法。
下面看代码
public class Thread2 implements Runnable{
public void run()
{
System.out.println("hello");
}
public static void main(String[] a)
{
new Thread1().start();
new Thread(new Thread2()).start();
}
}
class Thread1 extends Thread {
public void run() {
System.out.println("hello");
}
}
小结:继承Thread类会占用父类继承名额(java中是单根继承),而实现接口的方法看似麻烦,但是保留了父类的继承名额,所以推荐使用implements Runnable接口的方式来创建开启线程。
java多线程信息共享问题
售票问题,四个窗口同时售票,如何保证售票口的信息互通,确保售票口售出票数正确性。
Java里提供了volatile关键字与synchronized互斥锁机制。
volatile
确保线程中信息发生变化,其他线程都能同步共享。
由于java的工作机制以及内存模型,一个线程的数据来源是来自于工作缓存中,工作缓存不能及时与主存读写数据,导致数据的不同步现象,加了volatile关键字后,一旦关键数据发生变化,就会通知其他线程,此处数据已改变。
synchronized
互斥锁,通过给关键代码段或者函数加锁,达到一段代码块同时只能由一个线程调用执行的目的,这样做的好处在于确保了数据的安全性。
(小声bb:这样做也太呆了吧,眼瞅着别的售票员正在卖票,要看着他卖完才能卖~)
public class ThreadDemo3 {
public static void main(String[] args) {
TestThread3 t = new TestThread3();
new Thread(t, "Thread-0").start();
new Thread(t, "Thread-1").start();
new Thread(t, "Thread-2").start();
new Thread(t, "Thread-3").start();
}
}
class TestThread3 implements Runnable {
private volatile int tickets = 100; // 多个 线程在共享的
public void run() {
while (true) {
sale();
try {
Thread.sleep(100);
} catch (Exception e) {
System.out.println(e.getMessage());
}
if (tickets <= 0) {
break;
}
}
}
public synchronized void sale() { // 同步函数
if (tickets > 0) {
System.out.println(Thread.currentThread().getName() + " is saling ticket " + tickets--);
}
}
}