import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.wfl.Study.entity.Person;
import com.wfl.Study.entity.Student;
/**
* Hello world!
*
*/
class thread extends Thread{ //必须要加 @Override,因为Thread类已经有了ruan方法,需要重写。
private Object lock;
private static int count;
//synchronized修饰普通方法,锁定的是当前对象.一次只能有一个线程进入同一个对象实例的method()方法.
private synchronized void method(){
int j=10;
for (int i = 0; i< 10; i++) {
j=j--;
count=count+1;
System.out.println("继承的方式...i:" + i);
}
}
//类锁,即便是创建两个实例对象,两个实例对象也是操作同一个静态变量,同一把锁。
private static synchronized void method02(){
int j=10;
for (int i = 0; i< 10; i++) {
j=j--; //上面的synchronized同时修饰静态方法和实例方法,结果交替运行,证明类锁和对象锁是两个不同的锁,控制不同的区域,互不干扰.
count=count+1;
System.out.println("继承的方式...i:" + i);
}
}
public thread(Object lock){
this.lock=lock;
}
@Override
public void run() {
synchronized(lock){ //可以传成员变量lock(对象锁);也可以传this(类锁)
System.out.println("继承方式开始执行哈。。。"+System.currentTimeMillis());
for (int i = 0; i< 10; i++) {
System.out.println("继承的方式...i:" + i);
}
try {
//调用wait方法是当前线程处于等待状态,会释放当前的锁资源,直到其他线程调用notify方法;该方法释放掉了锁,再调用notify方法后,其他线程开始抢锁。
System.out.println("我在wait等待唤醒"+System.currentTimeMillis());
lock.wait(); //永远在synchronized的函数或对象中使用wait、notify、notifyAll,不然虚拟机会生成IllegalMonitorStateException。
System.out.println("我被唤醒"+System.currentTimeMillis());
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("继承方式执行结束。。。"+System.currentTimeMillis());
}
//类锁:thread.class;synchronized修饰静态方法;
synchronized(thread.class){
}
System.out.println(this.getName()); //直接调用getName获取线程名称
System.out.println(this.getId());
}
}
class runnable implements Runnable{ //不能加 @Override,因为接口就是要被子类实现的。
private Object lock; //
private int count;
public runnable(Object lock){
this.lock=lock;
}
public void run() {
String name = Thread.currentThread().getName();
if("add".equalsIgnoreCase(name)){
this.addCount();
}else{
this.decCount();
}
synchronized(lock){
System.out.println("接口方式开始唤醒哈。。。"+System.currentTimeMillis());
for (int i = 0; i< 10; i++) {
System.out.println("接口的方式...i:" + i);
}
//wait + notifyAll使两个线程之间通信 ;共享变量调用notifyAll通知其他等待的线程抢锁。
//notifyAll只对其他线程起作用,目的是唤醒wait的线程.
lock.notifyAll(); //永远在synchronized的函数或对象中使用wait、notify、notifyAll,不然虚拟机会生成IllegalMonitorStateException。
System.out.println("接口方式唤醒结束。。。"+System.currentTimeMillis());
//System.out.println(this.getName()); //实现的方式无法调用 getName方法,Runnable没有该方法
}
}
public void addCount(){
//synchronized块都是对象锁。
synchronized(this){
for (int i = 0; i< 10; i++) {
try {
count=count+1;
System.out.println("count的值...i:" + count);
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
}
}
public void decCount(){
//addCount 和 decCount方法中synchronized块 都是对象锁,即:同一个对象实例中,synchronized修饰的所有方法不能并行执行
synchronized(this){
for (int i = 0; i< 10; i++) {
try {
count=count-1;
System.out.println("count的值...i:" + count);
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
}
}
}
public class App
{
public static void main( String[] args ) throws NoSuchMethodException, SecurityException
{
Object lock = new Object(); //两个线程要共享的变量!!!
//Object lock02 = new Object();
System.out.println("-----多线程创建开始-----");
Thread thread01 = new thread(lock);
// Thread thread02 = new thread(lock);
//Thread thread02 = new thread(lock);
// try {
// Thread.sleep(3000);
// } catch (InterruptedException e1) {
// // TODO 自动生成的 catch 块
// e1.printStackTrace();
// } //调用Thread类的方法,使所有线程暂停一段时间!
thread01.start();
runnable thread001 = new runnable(lock);
//使用实现接口方式创建线程,可以对线程设置名字。
Thread thread02 = new Thread(thread001,"dec");
Thread thread03 = new Thread(thread001,"add");
try {
thread03.start();
//join使当前线程先执行,其他线程等待,可以让两/多个线程变为单线程.使线程有序执行
thread03.join();
thread02.start();
//可以停止正在执行得线程,这样的方法不安全,不建议使用。他会解除线程获取的所有锁定,如果线程处于一种不连贯的状态,其他线程有可能在那种状态下检查和修改他们,很难找到问题的所在。
thread02.stop();
//容易发生死锁,调用suspend()的时候,目标线程会停止,但是却仍然有之前获取的锁定。此时,其他线程都不能有访问线程锁定的资源,除非被"挂起"的线程恢复运行。需要在Thread类中有一个标志
//若标志指出线程应该挂起,便用wait()命其进入等待状态。若标志指出线程应当恢复,则用一个notify()重新启动线程。
thread02.suspend();
//interrupt()不会中断一个正在运行的线程。这一方法实际上完成的是:在线程受到阻塞时抛出一个中断信号,线程就得以退出阻塞的状态。
//如果线程被Object.wait,Thread.join,Thread.sleep三种方法之一阻塞,那么,它将接收到一个中断异常(InterruptedException),从而提早地终结被阻塞状态。
//如果线程没有被阻塞,这时调用interrupt()将不起作用。
thread02.interrupt();
//只是使当前线程重新回到可执行状态,所以执行yield()线程有可能在进入到可执行状态后马上又被执行.
// 只能使同优先级的线程有执行的机会。同样, yield()也不会释放锁资源.
//从执行状态(运行状态)变为可执行态(就绪状态)。
thread02.yield();
//线程分配时间片的多少就决定线程使用处理的多少,刚好对应线程优先级别这个概念。可以通过int priority(),里边可以填1-10,默认为5,10最高。
thread02.setPriority(5);
//确定线程在当前是否存活着,如果是可运行或被阻塞,这个方法返回true; 如果线程仍旧是new(新建)状态且不是可运行的, 或者线程死亡了,则返回false.
thread02.isAlive();
thread02.isInterrupted();
} catch (InterruptedException e1) {
// TODO 自动生成的 catch 块
e1.printStackTrace();
}
System.out.println("-----多线程创建结束-----");
// try {
// System.out.println("thread调用wait:9000");
// thread02.wait(200000);
// } catch (InterruptedException e2) {
// e2.printStackTrace();
// }
// System.out.println("thread调用notify");
// thread02.notifyAll();
// thread.currentThread().interrupt(); //该线程被中断,抛出异常
// System.out.println(thread.currentThread());
// System.out.println(thread.currentThread().getId());
// System.out.println(thread.currentThread().getName());
// System.out.println(thread.currentThread().getClass());
// System.out.println(thread.currentThread().getPriority());
// System.out.println(thread.currentThread().getState());
// System.out.println(thread.currentThread().interrupted()); //查看中断标志位是true(被中断)还是false(没有被中断)
}
}