java Thread 多线程
Java中的多线程是并发编程的核心,它允许程序同时执行多个任务,提高系统资源的利用率。在Java中,创建线程主要有两种方式: 1. **继承Thread类**:创建一个新的类,该类继承自Thread类,并重写其`run()`方法。在`run()`方法中放入线程要执行的代码。然后创建该类的实例并调用`start()`方法来启动线程。例如: ```java class MyThread extends Thread { @Override public void run() { // 线程执行的代码 } } MyThread thread = new MyThread(); thread.start(); ``` 2. **实现Runnable接口**:创建一个类实现Runnable接口,覆盖`run()`方法。然后将这个类的实例作为参数传递给Thread类的构造器,创建Thread对象并调用`start()`。这种方式避免了单继承的限制,因为Java不支持多重继承。例如: ```java class MyRunnable implements Runnable { @Override public void run() { // 线程执行的代码 } } Thread thread = new Thread(new MyRunnable()); thread.start(); ``` 线程的状态管理是多线程编程的重要部分。Java提供了多种控制线程的方法: - `setDaemon(true)`:将线程设置为守护线程,当所有非守护线程(用户线程)结束时,守护线程也会自动结束。 - `notify()`:唤醒在此对象监视器上等待的单个线程。如果所有线程都在此对象上等待,则会选择一个线程唤醒。 - `notifyAll()`:唤醒在此对象监视器上等待的所有线程。 - `interrupt()`:中断线程。如果线程正在阻塞(例如在`sleep()`, `wait()`, 或者`join()`),则会抛出`InterruptedException`。 在多线程环境中,同步是必不可少的,以确保共享数据的正确访问。Java提供了`synchronized`关键字来实现线程同步。当一个线程在`synchronized`块中执行时,其他试图进入同一块的线程会被阻塞,直到当前线程完成执行。例如: ```java class Tickets { private int tick = 100; public void run() { while (tick > 0) { synchronized (this) { if (tick > 0) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().toString() + "sale:" + tick--); } } } } } ``` 在这个例子中,`tick`是共享数据,使用`synchronized (this)`保证了对`tick`的修改是线程安全的。`this`代表了Tickets对象本身,即同步锁。 等待和唤醒机制是多线程间的通信方式。`wait()`, `notify()`, 和 `notifyAll()`方法都需要在同步上下文中调用,通常在`synchronized`块内。等待线程调用`wait()`后会释放同步锁进入等待状态,直到其他线程调用同一锁的`notify()`或`notifyAll()`来唤醒它。注意,等待和唤醒必须基于同一个锁,否则会导致死锁或唤醒错误的线程。 Java中的多线程通过Thread类和Runnable接口实现,通过`synchronized`关键字确保线程安全,利用`wait()`, `notify()`, 和 `notifyAll()`进行线程间通信,有效地提高了程序的并发性能和资源利用率。在编写多线程程序时,合理地管理和同步线程,避免死锁和竞态条件是至关重要的。