Java同时开启两个线程

在Java中,线程是一种执行多个任务的方式。一个Java程序至少有一个线程,即主线程。然而,在某些情况下,需要同时执行多个任务,这就需要开启多个线程。

创建线程

在Java中,有两种常见的方式来创建线程:

  1. 继承Thread类
  2. 实现Runnable接口

继承Thread类

public class MyThread extends Thread {
    @Override
    public void run() {
        // 线程要执行的任务
        System.out.println("Thread 1 is running.");
    }
}

public class Main {
    public static void main(String[] args) {
        MyThread thread1 = new MyThread();
        thread1.start();
    }
}

在上面的代码中,我们创建了一个继承自Thread类的自定义线程类MyThread。在run方法中定义了线程要执行的任务。在主线程中,我们创建了一个MyThread对象,并调用start方法来启动线程。start方法会自动调用run方法来执行线程任务。

实现Runnable接口

public class MyRunnable implements Runnable {
    @Override
    public void run() {
        // 线程要执行的任务
        System.out.println("Thread 2 is running.");
    }
}

public class Main {
    public static void main(String[] args) {
        MyRunnable runnable = new MyRunnable();
        Thread thread2 = new Thread(runnable);
        thread2.start();
    }
}

在上面的代码中,我们创建了一个实现了Runnable接口的自定义线程类MyRunnable。在run方法中定义了线程要执行的任务。在主线程中,我们创建了一个MyRunnable对象,并将其作为参数传递给Thread构造函数来创建一个新的线程对象。然后调用start方法来启动线程。

同时开启两个线程

现在,我们来同时开启两个线程:

public class MyThread extends Thread {
    @Override
    public void run() {
        // 线程要执行的任务
        System.out.println("Thread 1 is running.");
    }
}

public class MyRunnable implements Runnable {
    @Override
    public void run() {
        // 线程要执行的任务
        System.out.println("Thread 2 is running.");
    }
}

public class Main {
    public static void main(String[] args) {
        MyThread thread1 = new MyThread();
        MyRunnable runnable = new MyRunnable();
        Thread thread2 = new Thread(runnable);

        thread1.start();
        thread2.start();
    }
}

在上面的代码中,我们同时创建了一个继承Thread类的线程和一个实现Runnable接口的线程。然后分别调用它们的start方法来启动线程。这样,两个线程就会同时执行各自的任务。

线程安全问题

在多线程环境中,可能会出现线程安全问题。线程安全问题指的是多个线程同时访问共享资源时可能导致的数据不一致或者程序出现异常的情况。

为了避免线程安全问题,可以使用synchronized关键字来控制对共享资源的访问。synchronized关键字可以用在方法上或者代码块上,保证同一时间只有一个线程能够执行被synchronized修饰的方法或者代码块。

下面是一个使用synchronized关键字的示例:

public class Counter {
    private int count = 0;

    public synchronized void increment() {
        count++;
    }

    public synchronized int getCount() {
        return count;
    }
}

public class MyThread extends Thread {
    private Counter counter;

    public MyThread(Counter counter) {
        this.counter = counter;
    }

    @Override
    public void run() {
        for (int i = 0; i < 1000; i++) {
            counter.increment();
        }
    }
}

public class Main {
    public static void main(String[] args) {
        Counter counter = new Counter();
        MyThread thread1 = new MyThread(counter);
        MyThread thread2 = new MyThread(counter);

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

        try {
            thread1.join();
            thread2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("Count: " + counter.getCount());
    }
}

在上面的代码中,我们创建了一个Counter类来记录一个计数器的值。increment方法和getCount方法都使用了synchronized关键字来保证对count变量