17线程
Start的是让线程进入就绪状态,等待cpu来调度.
17.1join
public static void main(String[] args) {
MyThread2 t1 = new MyThread2("abcde");
t1.start();
try {
t1.join(); 在此将t1的线程合并到主线程,并且直到t1执行完后才能接着往下//执行
}catch (InterruptedException e) {}
for(int i=1;i<=10;i++){
System.out.println("i am main thread");
}
}
}
class MyThread2 extends Thread {
MyThread2(String s){
super(s);
}
public void run(){
for(int i =1;i<=10;i++){
System.out.println("i am "+getName());
try {
sleep(1000);
} catch (InterruptedException e) {
return;
}
}
}
17.2 yield
让出一次CPU,只是很小一段
17.3 Priority
Priority的优先级越高,则CPU每次分配的时间越长
17.4正常停止线程的方法
public class TestThread4 {
publicstatic void main(String args[]){
Runner4r = new Runner4();
Thread t = new Thread(r);
t.start();
for(int i=0;i<100000;i++){
if(i%10000==0 &i>0)
System.out.println("inthread main i=" + i);
}
System.out.println("Thread main is over");
r.shutDown();//通过调用shutDown()将flag设置为false,在run()结束,一旦run结//束线程就结束
//t.stop();
}
}
class Runner4 implements Runnable {
private boolean flag=true;
publicvoid run() {
inti = 0;
while(flag==true) {
System.out.print("" + i++);
}
}
public void shutDown() {
flag = false;
}
}
17.5线程的同步
public class TestSync implements Runnable {
Timer timer = new Timer();
public static void main(String[] args) {
TestSync test = new TestSync();
Thread t1 = new Thread(test);
Thread t2 = new Thread(test);
t1.setName("t1");
t2.setName("t2");
t1.start();
t2.start();
}
public void run(){
timer.add(Thread.currentThread().getName());
}
}
class Timer{
private static int num = 0;
public synchronized void add(String name){
//synchronized (this) {
num ++;
try {Thread.sleep(1);}
catch (InterruptedException e) {}
System.out.println(name+", 你是第"+num+"个使用timer的线程");
//如果不加synchronized则两次输出的num都是2
//}
}
}
17.6线程的死锁
public class TestDeadLock implementsRunnable {
publicint flag = 1;
staticObject o1 = new Object(), o2 = new Object();
publicvoid run() {
System.out.println("flag="+ flag);
if(flag== 1) {
synchronized(o1){ //锁住o1
try{
Thread.sleep(500);
}catch (Exception e) {
e.printStackTrace();
}
synchronized(o2){ //需要锁住o2,要放在o1锁里面才可以
System.out.println("1");
}
}
}
if(flag== 0) {
synchronized(o2){
try{
Thread.sleep(500);
}catch (Exception e) {
e.printStackTrace();
}
synchronized(o1){ / /需要锁住o1,要放在o2锁里面才可以
System.out.println("0");
}
}
}
}
publicstatic void main(String[] args) {
TestDeadLocktd1 = new TestDeadLock();
TestDeadLocktd2 = new TestDeadLock();
td1.flag= 1;
td2.flag= 0;
Threadt1 = new Thread(td1);
Threadt2 = new Thread(td2);
t1.start();
t2.start();
}
}
17.7关于锁定的究竟是什么
public class TT implements Runnable {
intb = 100;
//锁住的其实是访问m1()这个方法的对象,而不是b这个对象
publicsynchronized void m1() throws Exception{
b= 1000;
Thread.sleep(5000);
System.out.println("b= " + b);
}
publicvoid m2(){
System.out.println(b);//输出的结果是1000并且是在输出完之后才输出b=1000
}
publicvoid run() {
try{
m1();
}catch(Exception e) {
e.printStackTrace();
}
}
publicstatic void main(String[] args) throws Exception {
TT tt = new TT();
Thread t = new Thread(tt);
t.start();
Thread.sleep(1000);//确保m1执行
tt.m2();
}
}
Java的synchronized使用方法总结
1. 把synchronized当作函数修饰符时
这也就是同步方法,那这时synchronized锁定的是哪个对象呢?它锁定的是调用这个同步方法对象。也就是说,当一个对象P1在不同的线程中执行这个同步方法时,它们之间会形成互斥,达到同步的效果。但是这个对象所属的Class所产生的另一对象P2却可以任意调用这个被加了synchronized关键字的方法。
同步块,示例代码如下:
public void method3(SomeObject so)
{
synchronized(so)
{
//…..
}
}
这时,锁就是so这个对象,谁拿到这个锁谁就可以运行它所控制的那段代码。当有一个明确的对象作为锁时,就可以这样写程序,但当没有明确的对象作为锁,只是想让一段代码同步时,可以创建一个特殊的instance变量(它得是一个对象)来充当锁。
3.将synchronized作用于static 函数,示例代码如下:
Class Foo
{
public synchronized static voidmethodAAA() // 同步的static 函数
{
//….
}
public void methodBBB()
{
synchronized(Foo.class) // class literal(类名称字面常量)
}
}
代码中的methodBBB()方法是把classliteral作为锁的情况,它和同步的static函数产生的效果是一样的,取得的锁很特别,是当前调用这个方法的对象所属的类(Class,而不再是由这个Class产生的某个具体对象了)。
即Synchronized锁定的是调用方法的对象或者是类,呗锁定的对象在同一时间只能访问一个带有synchronized 的函数,对于不带有synchronized的函数随便访问