1.线程的创建:
接触过java的人都知道基本实现有3种:创建Thread子类、实现runnable接口、创建callable的接口实现类
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class CreateThread {
public static void main(String[] args) {
//通过创建子类创建线程
Thread thread1 = new ThreadTest("Thread Test");
thread1.start();
//通过实现runnable创建线程
Thread thread2 = new Thread(new RunnableTest("Runnable Test"));
thread2.start();
//通过callable创建线程
FutureTask<String> ft = new FutureTask<>(new CallableTest("Callable Test"));
Thread thread3 = new Thread(ft);
thread3.start();
try {
System.out.println("callable 返回了结果:"+ft.get());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class ThreadTest extends Thread{
private String name;
public ThreadTest(String name) {
this.name = name;
}
@Override
public void run() {
System.out.println("Thread: " + name + "run");
}
}
class RunnableTest implements Runnable{
private String name;
public RunnableTest(String name) {
this.name = name;
}
@Override
public void run() {
System.out.println("Thread: " + name + "run");
}
}
class CallableTest implements Callable<String>{
private String name;
public CallableTest(String name) {
this.name = name;
}
@Override
public String call() throws Exception {
System.out.println("Thread: " + name + "run");
return "callable 有返回值";
}
}
创建方式的选择:
通常情况下假如你需要返回线程执行结果你则需要callable,不然创建thread子类与实现runnable并没有确定的答案,他们都能实现你的需求。但是线程池可以有效的管理实现了runnable接口的线程,假如线程池满了,之后的线程会排队等待知道线程池空闲出来。而通过thread子类来实现会复杂些。引用http://tutorials.jenkov.com/java-concurrency/creating-and-starting-threads.html中Subclass or Runnable?
2. 线程的其他常见方法
join():通俗的讲就是将制定线程加入到当前线程。实例:
public class JoinTest {
public static void main(String[] args) {
System.out.println("Main Thread start");
Thread joinThread = new Thread(new TestJoin());
joinThread.start();
try {
joinThread.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Main Thread end");
}
}
class TestJoin implements Runnable{
@Override
public void run() {
try {
Thread.sleep(2000);
System.out.println("join here");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
输出:
Main Thread start
join here
Main Thread end
sleep():让当前执行的线程进入休眠状态,sleep将会让出cpu给其他线程,但是他的监控状态依然保持,指定时间到了之后自动恢复运行状态。sleep不会释放对象锁。
interrupt():中断。当调用interrupt()方法的时候,只是设置了要中断线程的中断状态,而此时被中断的线程的可以通过isInterrupted()或者是interrupted()方法判断当前线程的中断状态是否标志为中断。
wait()与notify():
如果对象调用了wait方法就会使持有该对象的线程把该对象的控制权交出去,然后处于等待状态。
如果对象调用了notify方法就会通知某个正在等待这个对象的控制权的线程可以继续运行。
3.生产者消费者
package com.Thead;
import java.util.ArrayList;
import java.util.List;
public class Container {
private List<Integer> list = new ArrayList<>();
private int MAX_NUM = 5;
public synchronized void put(Integer num){
while(list.size() == MAX_NUM){
try {
System.out.println("container is full");
this.wait(); //使当前线程进入等待状态
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.notify(); //唤醒当前访问对象的其他线程
list.add(num);
System.out.println("producer add a num " + num);
}
public synchronized void get(){
while(list.size() == 0){
try {
System.out.println("container is empty。。。");
this.wait(); //使当前线程进入等待状态
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.notify(); //唤醒当前访问对象的其他线程
int x = list.remove(0);
System.out.println("customer remove a num "+x);
}
}
package com.Thead;
import java.util.Random;
public class Producer implements Runnable{
private Container container;
public Producer(Container container) {
this.container = container;
}
@Override
public void run() {
for(int i = 0; i < 10; i++){
int num = new Random().nextInt(10);
container.put(num);
}
}
}
package com.Thead;
public class Consumer implements Runnable{
private Container container;
public Consumer(Container container) {
this.container = container;
}
@Override
public void run() {
for(int i = 0; i < 10; i++){
container.get();
}
}
}
package com.Thead;
public class Main {
public static void main(String[] args) {
Container container = new Container();
Producer producer = new Producer(container);
Consumer consumer = new Consumer(container);
Thread p = new Thread(producer);
Thread c = new Thread(consumer);
p.start();
c.start();
}
}
执行结果
container is empty。。。
producer add a num 5
customer remove a num 5
producer add a num 6
customer remove a num 6
producer add a num 7
customer remove a num 7
producer add a num 1
customer remove a num 1
producer add a num 0
customer remove a num 0
producer add a num 9
customer remove a num 9
......