开启线程的方法;
1.new Thread(xx).start();
2.线程池:
实现线程任务的方法:
1.不带返回值:实现Runnable类run(),
2.实现带返回值的任务:RunnableFuture,代表子类:FutureTask
线程生命周期(状态)
public enum State {
1.NEW //新建,未开始执行
2.RUNNABLE //正在执行,但是可能等待processor(处理器)资源
3.BLOCKED // 阻塞状态,等待获取监视器锁monitor lock,以便后面进入同步方法 或 调用object wait之后重新进入同步方法。
4.WAITING // 一直等待的线程会是WAITING状态,无限期等待其他线程执行的线程持有的状态
* Thread state for a waiting thread.
* A thread is in the waiting state due to calling one of the
* following methods:
* <ul>
* <li>{@link Object#wait() Object.wait} with no timeout</li>
* <li>{@link #join() Thread.join} with no timeout</li>
* <li>{@link LockSupport#park() LockSupport.park}</li>
* </ul>
5.TIMED_WAITING
* Thread state for a waiting thread with a specified waiting time.
* A thread is in the timed waiting state due to calling one of
* the following methods with a specified positive waiting time:
* <ul>
* <li>{@link #sleep Thread.sleep}</li>
* <li>{@link Object#wait(long) Object.wait} with timeout</li>
* <li>{@link #join(long) Thread.join} with timeout</li>
* <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>
* <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>
* </ul>
6.TERMINATED //线程执行完毕或中断,线程退出
/**
* Thread state for a terminated thread.
* The thread has completed execution.
*/
}
重点api
1.join 让线程暂停 阻塞线程,使用了object的wait(0),等待唤醒
Causes the current thread to wait until either another thread invokes the
* {@link java.lang.Object#notify()} method or the
* {@link java.lang.Object#notifyAll()} method for this object, or a
* specified amount of time has elapsed.
使用场景:主线程等待子线程执行完毕。
public class JoinExample
{
public static void main(String[] args) throws InterruptedException
{
Thread t = new Thread(new Runnable()
{
public void run()
{
System.out.println("First task started");
System.out.println("Sleeping for 2 seconds");
try
{
Thread.sleep(2000);
} catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println("First task completed");
}
});
Thread t1 = new Thread(new Runnable()
{
public void run()
{
System.out.println("Second task completed");
}
});
t.start();
t.join();
t1.start();
}
}
2.Thread.yield() 非阻塞,使用场景:消费者生产者轮流执行。
- Yield是一个静态的原生(native)方法
- Yield告诉当前正在执行的线程把运行机会交给线程池中拥有相同优先级的线程。
- Yield不能保证使得当前正在运行的线程迅速转换到可运行的状态
- 它仅能使一个线程从运行状态转到可运行状态,而不是等待或阻塞状态
public class YieldExample
{
public static void main(String[] args)
{
Thread producer = new Producer();
Thread consumer = new Consumer();
producer.setPriority(Thread.MIN_PRIORITY); //Min Priority
consumer.setPriority(Thread.MAX_PRIORITY); //Max Priority
producer.start();
consumer.start();
}
}
class Producer extends Thread
{
public void run()
{
for (int i = 0; i < 5; i++)
{
System.out.println("I am Producer : Produced Item " + i);
Thread.yield();
}
}
}
class Consumer extends Thread
{
public void run()
{
for (int i = 0; i < 5; i++)
{
System.out.println("I am Consumer : Consumed Item " + i);
Thread.yield();
}
}
}
\\添加Thread.yield();会让消费者和生产者轮流执行
wait()和sleep()区别
sleep :使当前执行的线程在指定的毫秒数内休眠(暂时停止执行),这取决于系统计时器和调度程序的精度和准确性。The thread does not lose ownership of any monitors.
wait:object方法,只能由其他线程notify或notifyall,会导致丢弃监视器。
线程必须先持有监视器,线程释放监视器,等待其他线程唤醒。
wait重载方法:(3个)
wait()
wait(long millis)
wait(long millis, int nanos)
下面两个表示等待多长时间,自己唤醒。
注意:调用obj.wait方法需要注意的是,当前线程必须获取到了obj的Monitor,才能去调用其wait方法,即wait必须放在同步方法或同步代码块中。(调用的是obj.wait(),而不是Thread.currentThread.wait())
monitor就是实现锁的方式。
entermonitor就是获得某个对象的lock(owner是当前线程)
leavemonitor就是释放某个对象的lock
Monitor的概念
Java虚拟机给每个对象和class字节码都设置了一个监听器Monitor,用于检测并发代码的重入,同时在Object类中还提供了notify和wait方法来对线程进行控制。
java通过synchronized关键字实现线程同步来获取对象的Monitor。synchronized同步分为以下两种方式:
静态方法和非静态方法synchronized的区别
public synchronized void set() {
}
public static synchronized void set() {
}
分析:
1.synchronized分别修饰了非静态方法和静态方法。
2.非静态方法,需要获取当前对象this的Monitor,获取后,其他需要获取该对象的Monitor的线程会被堵塞。
3.静态方法,需要获取该类字节码的Monitor(因为static方法不属于任何对象,而是属于类的方法),获取后,其他需要获取字节码的Monitor的线程会被堵塞。
thread.setDaemon(True)
特点:当所有线程为Daemon线程,jvm退出。
The Java Virtual Machine exits when the only threads running are all daemon threads
resume()是恢复suspend()的,suspend容易死锁所以废弃。