实现多线程的方式:
实现多线程的方式有多种,这里只列举两种常用的,而第一种继承Thread的方式无法实现多窗口卖票。
一,继承Thread方式:
特点:多线程多实例,无法实现资源的共享。
例子:
1 package com.demo.study.multithreading; 2 3 public class MyThread extends Thread{ 4 5 private int i = 10; 6 // 可以自行定义锁,也可以使用实例的锁 7 Object mutex = new Object(); 8 public void selltickets(){ 9 10 synchronized (mutex) { 11 12 if(i>0){ 13 i--; 14 //getName()获取线程的名字 15 System.out.println(Thread.currentThread().getName()+" :"+ i); 16 } 17 } 18 } 19 20 @Override 21 public void run() { 22 while(i>0){ 23 24 selltickets(); 25 } 26 } 27 }
启动线程:
1 package com.demo.study.multithreading; 2 3 public class Test { 4 5 public static void main(String[] args) { 6 //继承Thread方式:多线程多实例,无法实现资源的共享 7 MyThread myThread1 = new MyThread(); 8 MyThread myThread2 = new MyThread(); 9 //给线程命名 10 myThread1.setName("线程1"); 11 myThread2.setName("线程2"); 12 myThread1.start(); 13 myThread2.start(); 14 } 15 }
运行结果:
二,实现Runnable方式:
特点:多线程单实例,可实现资源的共享
例子:实现多窗口卖票:
1 package com.demo.study.multithreading; 2 3 public class MyThreadImpl implements Runnable { 4 5 private int tickets = 10; 6 7 public void sellTickets() { 8 9 synchronized (MyThreadImpl.class) { 10 if (tickets > 0) { 11 12 tickets--; 13 System.out.println(Thread.currentThread().getName() + "正在卖票,还剩下" + tickets + "张"); 14 } 15 } 16 } 17 18 @Override 19 public void run() { 20 21 while (tickets > 0) { 22 sellTickets(); 23 try { 24 // 休眠一秒,让执行的效果更明显 25 Thread.sleep(100); 26 } catch (InterruptedException e) { 27 e.printStackTrace(); 28 } 29 } 30 } 31 }
启动线程:
注意:线程的启动是通过Thread中的start()方法,而线程的启动,只运行了实例类中的重写的run()方法。
void |
start() 使该线程开始执行;Java 虚拟机调用该线程的 run 方法。 |
1 package com.demo.study.multithreading; 2 3 public class Test { 4 5 public static void main(String[] args) { 6 7 //只创建一个实例 8 MyThreadImpl threadImpl = new MyThreadImpl(); 9 //将上面创建的唯一实例放入多个线程中,Thread类提供了多个构造方法,见下图(构造方法摘要) 10 Thread thread1 = new Thread(threadImpl, "窗口1"); 11 Thread thread2 = new Thread(threadImpl, "窗口2"); 12 thread1.start(); 13 thread2.start(); 14 15 } 16 }
构造方法摘要 | |
---|---|
Thread() 分配新的 Thread 对象。 |
|
Thread(Runnable target)
分配新的 |
|
Thread(Runnable target, 分配新的 Thread 对象。 |
|
Thread(String name)
分配新的 |
|
Thread(ThreadGroup group, Runnable target)
分配新的 |
|
Thread(ThreadGroup group, Runnable target, 分配新的 Thread 对象,以便将 target 作为其运行对象,将指定的 name 作为其名称,并作为 group 所引用的线程组的一员。 |
|
Thread(ThreadGroup group, Runnable target, 分配新的 Thread 对象,以便将target 作为其运行对象,将指定的 name 作为其名称,作为 group 所引用的线程组的一员,并具有指定的堆栈大小。 |
|
Thread(ThreadGroup group, String name)
分配新的 |
运行结果:
三、同步锁与资源共享:
执行synchronized部分代码的时候必须需要对象锁,而一个对象只有一个锁,只有执行完synchronized里面的代码后释放锁,其他线程才可以获得锁,那么就保证了同一时刻只有一个线程访问synchronized里面的代码。实现资源共享的关键是,只有一个实例,synchronized使用的是同一把锁,用实例的锁或者定义一个实例。这就需要使用实现Runnable接口的方式,实现多线程,这样传入的是一个实例。继承Thread的方式,传入的是多个实例,每个实例都有一个锁,那就无法实现控制。
时间: 2024-10-15 14:56:07