关于多线程Thread方法的几点总结,
- isAlive方法判断线程是否存活 ,wait方法传入参数0无限期等待
- yield方法让出cpu执行权大家再次公平竞争
- join方法等待线程执行完一起运行,比如子线程运行循环累加,主线程运行at.join(0),一直等他累加完,主线程在运行下面的打印语句,相当于主线程在等待子线程的运行完成
- 守护进程不主导虚拟机的运行,守护进程设置方法为thread.daemon(true),必须在start方法前,不然抛错且无效,如果main中只有设置守护线程且start,不论线程中如何写死循环,程序直接结束
- 多线程中的关于synchronize关键字使用
注意notify wait以及相对应的两个all方法都是Object对象的方法,必须拿到锁之后才能执行这些方法
指定对象加锁,进入同步代码前需要获得给定对象的锁 TestSyn.java 代码解释请看注释
package com.gzr.study;
/**
*
* @author gzr
* synchronized 关键字
* 制定加锁对象 :指定对象加锁,进入同步代码前需要获得给定对象的锁 TestSyn.java
* 直接作用于实例方法:相当于对当前实例加锁 需要获得当前实例的锁 TestSyn2.java
* 直接作用于静态方法:相当于对当前类加锁,进入同步代码钱需要获得当前类的锁 SimpleWaitNotify.java
*/
public class TestSyn implements Runnable{
/**
* testSyn为实例对象作为锁
*/
static TestSyn testSyn=new TestSyn();
static int i=0;
public static void main(String[] args) throws InterruptedException {
Thread t1=new Thread(testSyn);
Thread t2=new Thread(testSyn);
t1.start();t2.start();
/**
* t1 t2执行完之后 主线程在运行打印语句
*/
t1.join();t2.join();
System.out.println(i);
}
@Override
public void run() {
// TODO Auto-generated method stub
for(int j=0;j<100;j++) {
synchronized (testSyn) {
i++;
}
}
}
}
直接作用于实例方法:相当于对当前实例加锁 需要获得当前实例的锁 TestSyn2.java
package com.gzr.study;
/**
*
* @author gzr
* synchronized 关键字
* 制定加锁对象 :指定对象加锁,进入同步代码前需要获得给定对象的锁 TestSyn.java
* 直接作用于实例方法:相当于对当前实例加锁 需要获得当前实例的锁 TestSyn2.java
* 直接作用于静态方法:相当于对当前类加锁,进入同步代码钱需要获得当前类的锁 SimpleWaitNotify.java
*/
public class TestSyn2 implements Runnable{
/**
* testSyn为实例对象作为锁
*/
static TestSyn2 testSyn=new TestSyn2();
static int i=0;
public static void main(String[] args) throws InterruptedException {
Thread t1=new Thread(testSyn);
Thread t2=new Thread(testSyn);
/*
* 这是错误的调用方法因为作用于实例方法上的,必须是同一实例才能同步,这里new到两个对象不会产生同步效果
* Thread t1=new Thread(new TestSyn2());
Thread t2=new Thread(new TestSyn2());*/
t1.start();t2.start();
t1.join();t2.join();
System.out.println(i);
}
/**
* synchronized关键字作用于方法上
*/
public synchronized void increase() {
i++;
}
@Override
public void run() {
// TODO Auto-generated method stub
for(int j=0;j<10000;j++) {
increase();
}
}
}
直接作用于静态方法:相当于对当前类加锁,进入同步代码钱需要获得当前类的锁 SimpleWaitNotify.java
package com.gzr.study;
public class SimpleWaitNotify {
final static Object object=new Object();
public static class T1 extends Thread{
@Override
public void run() {
// TODO Auto-generated method stub
/**
* object.wait();放在这里运行会报错
*/
synchronized (object) {
System.out.println(System.currentTimeMillis()+",T1 start");
try {
System.out.println(System.currentTimeMillis()+",T1 wait");
/**
* 注意wait和notify等方法都必须在你拿到锁之后才有资格做
* t1 放弃刚才拿到的锁对象,大家重新开始竞争锁
* 在哪wait就在哪醒
*/
object.wait();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
System.out.println(System.currentTimeMillis()+",T1 End");
}
}
}
public static class T2 extends Thread{
@Override
public void run() {
// TODO Auto-generated method stub
synchronized (object) {
System.out.println(System.currentTimeMillis()+",T2 start");
try {
/**
* notify会随机唤醒一个拥有当前锁的监视器的进程,这里只有t1所以唤醒t1
* notify唤醒t1 让他有机会拿到锁执行下去
*/
object.notify();
System.out.println(System.currentTimeMillis()+",T2 notify");
System.out.println(System.currentTimeMillis()+",T2 End");
/**
* 完了之后休眠2秒,t2 End两秒之后 t1 End被打印
*/
Thread.sleep(2000);
/**
* t2 放弃刚才拿到的锁对象,大家重新开始竞争锁
* 在哪wait就在哪醒
*/
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
Thread t1=new T1();
Thread t2=new T2();
t1.start();t2.start();
/**
* 运行结果如下
* 1512191804823,T1 start
1512191804824,T1 wait
1512191804824,T2 start
1512191804824,T2 notify
1512191804824,T2 End
1512191806825,T1 End
T2 End两秒后T1 End
*/
}
}
网友评论