多线程的基础方法,作此记录。
wait
package com.kornzhou.javademo.concurrentprogramming.wait;
/**
* @author admin
*/
public class WaitDemo {
// wait notify 要作用于同一对象
// 调用wait后,线程会释放对monitor对象的所有权
//
public static void main(String[] args) {
MyRunnable runnable = new MyRunnable();
for (int i = 0; i < 5; i++) {
Thread thread = new Thread(runnable, ("线程-" + i));
thread.start();
}
}
static class MyRunnable implements Runnable {
private int count = 0;
@Override
synchronized public void run() {
for (int i = 0; i < 10; i++) {
String name = Thread.currentThread().getName();
count++;
System.out.println(name + " : " + count);
if ("线程-0".equals(name) && i == 0) {
try {
System.out.println(name + " 等待中...");
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if ("线程-1".equals(name) && i == 0) {
try {
System.out.println(name + " 等待中...");
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if ("线程-2".equals(name) && i == 0) {
try {
// 保证 线程-0,线程-1先运行
System.out.println(name + " 等待5s后, 执行notifyAll()");
wait(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
notifyAll();
}
}
}
}
}
线程-0 : 1
线程-0 等待中...
线程-1 : 2
线程-1 等待中...
线程-2 : 3
线程-2 等待5s后, 执行notifyAll()
线程-3 : 4
线程-3 : 5
线程-3 : 6
线程-3 : 7
线程-3 : 8
线程-3 : 9
线程-3 : 10
线程-3 : 11
线程-3 : 12
线程-3 : 13
线程-4 : 14
线程-4 : 15
线程-4 : 16
线程-4 : 17
线程-4 : 18
线程-4 : 19
线程-4 : 20
线程-4 : 21
线程-4 : 22
线程-4 : 23
线程-2 : 24
线程-2 : 25
线程-2 : 26
线程-2 : 27
线程-2 : 28
线程-2 : 29
线程-2 : 30
线程-2 : 31
线程-2 : 32
线程-1 : 33
线程-1 : 34
线程-1 : 35
线程-1 : 36
线程-1 : 37
线程-1 : 38
线程-1 : 39
线程-1 : 40
线程-1 : 41
线程-0 : 42
线程-0 : 43
线程-0 : 44
线程-0 : 45
线程-0 : 46
线程-0 : 47
线程-0 : 48
线程-0 : 49
线程-0 : 50
Disconnected from the target VM, address: '127.0.0.1:59909', transport: 'socket'
Process finished with exit code 0
sleep
package com.kornzhou.javademo.concurrentprogramming.wait;
/**
* sleep只是暂时让出CPU执行权,并不会释放锁
* @author admin
*/
public class SleepDemo {
public static void main(String[] args) {
final SleepDemo sleepDemo = new SleepDemo();
for (int i = 0; i < 3; i++) {
new Thread(() -> {
sleepDemo.sleepMethod();
}).start();
}
}
public void sleepMethod() {
System.out.println("sleep start " + Thread.currentThread().getName());
try {
synchronized (this) {
Thread.sleep(2000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("sleep end " + Thread.currentThread().getName());
}
public synchronized void waitMethod() {
System.out.println("wait start " + Thread.currentThread().getName());
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("wait end " + Thread.currentThread().getName());
}
}
sleep start Thread-1
sleep start Thread-0
sleep start Thread-2
sleep end Thread-1
sleep end Thread-2
sleep end Thread-0
yield
package com.kornzhou.javademo.concurrentprogramming.wait;
/**
* @author admin
*/
public class YieldDemo {
public static void main(String[] args) {
Runnable runnable = () -> {
System.out.println("start " + Thread.currentThread().getName());
for (int i = 0; i < 5; i++) {
System.out.println("end " + Thread.currentThread().getName() + " : " + i);
Thread.yield();
}
};
for (int i = 0; i < 2; i++) {
Thread thread = new Thread(runnable, "Thread-" + i);
thread.start();
}
}
}
start Thread-1
start Thread-0
end Thread-1 : 0
end Thread-0 : 0
end Thread-1 : 1
end Thread-0 : 1
end Thread-1 : 2
end Thread-1 : 3
end Thread-0 : 2
end Thread-1 : 4
end Thread-0 : 3
end Thread-0 : 4
join
package com.kornzhou.javademo.concurrentprogramming.wait;
/**
* @author admin
*/
public class JoinDemo {
public static void main(String[] args) {
for (int i = 0; i < 5; i++) {
Thread thread = new Thread(() -> {
System.out.println("start " + Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("end " + Thread.currentThread().getName());
});
thread.start();
try {
// 主线程休眠一秒,保证先执行打印thread的start...
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 主线程这行与thread的end...竞争输出
System.out.println("======= " + Thread.currentThread().getName());
try {
// main线程等待,优先thread执行后,main继续
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("当前线程执行完后,主线程继续循环,开始下一个线程创建。。。");
}
}
}
start Thread-0
end Thread-0
======= main
当前线程执行完后,主线程继续循环,开始下一个线程创建。。。
start Thread-1
======= main
end Thread-1
当前线程执行完后,主线程继续循环,开始下一个线程创建。。。
start Thread-2
======= main
end Thread-2
当前线程执行完后,主线程继续循环,开始下一个线程创建。。。
start Thread-3
======= main
end Thread-3
当前线程执行完后,主线程继续循环,开始下一个线程创建。。。
start Thread-4
======= main
end Thread-4
当前线程执行完后,主线程继续循环,开始下一个线程创建。。。
Disconnected from the target VM, address: '127.0.0.1:61058', transport: 'socket'
Process finished with exit code 0
附录
wait/notify是Object方法,要和锁一起使用,object.wait()/notify()
sleep相比wait不会释放锁,Thread.sleep()
yield暂停一会,Thread.yield()
join插队执行,thread.join()