Вот простой пример:
ThreadTest.java
public class ThreadTest
{
public static void main(String [] args)
{
MyThread t1 = new MyThread(0, 3, 300);
MyThread t2 = new MyThread(1, 3, 300);
MyThread t3 = new MyThread(2, 3, 300);
t1.start();
t2.start();
t3.start();
}
}
MyThread.java
public class MyThread extends Thread
{
private int startIdx, nThreads, maxIdx;
public MyThread(int s, int n, int m)
{
this.startIdx = s;
this.nThreads = n;
this.maxIdx = m;
}
@Override
public void run()
{
for(int i = this.startIdx; i < this.maxIdx; i += this.nThreads)
{
System.out.println("[ID " + this.getId() + "] " + i);
}
}
}
И некоторые результаты:
[ID 9] 1
[ID 10] 2
[ID 8] 0
[ID 10] 5
[ID 9] 4
[ID 10] 8
[ID 8] 3
[ID 10] 11
[ID 10] 14
[ID 10] 17
[ID 10] 20
[ID 10] 23
Объяснение - Каждый MyThread
пытается напечатать числа от 0 до 300, но они отвечают только за определенные области этого диапазона. Я решил разделить его по индексам, при этом каждый поток продвигается вперед по общему количеству потоков. Итак, t1
индексирует 0, 3, 6, 9 и т. Д.
Теперь, без ввода-вывода, такие тривиальные вычисления могут выглядеть так, как будто потоки выполняются последовательно, поэтому Я только что показал первую часть вывода. На моем компьютере после того, как этот выходной поток с идентификатором 10 завершится сразу, за ним следует 9, затем 8. Если вы поставите ожидание или выход, вы увидите его лучше:
MyThread.java
System.out.println("[ID " + this.getId() + "] " + i);
Thread.yield();
И файл output:
[ID 8] 0
[ID 9] 1
[ID 10] 2
[ID 8] 3
[ID 9] 4
[ID 8] 6
[ID 10] 5
[ID 9] 7
Теперь вы можете видеть выполнение каждого потока, досрочного отказа от управления и следующего выполнения.
Нет никакой гарантии, что ваши потоки выполняются одновременно, независимо от какого-либо тривиального примера, опубликованного кем-либо еще. Если ваша ОС предоставляет java-процессу только один процессор для работы, ваши Java-потоки все равно будут планироваться для каждого временного среза в циклическом режиме. Это означает, что никакие двое никогда не будут выполняться одновременно, но работа, которую они выполняют, будет чередоваться. Вы можете использовать инструменты мониторинга, такие как Java Visual VM (стандартная в JDK), чтобы наблюдать за потоками, выполняемыми в процессе Java.