目的:将自定义代码存储在run方法。让线程运行。
public class TreadDemo { public static void main(String[] args) { Demo d = new Demo(); d.start();//开启线程并执行该线程的run方法,如果写d.run()仅仅是对象调用方法, //而线程创建了,并没有运行,如果这里写d.run,会先执行demorun然后执行"main在运行!!! //,因为创建了线程,但是没有运行,相当于只有一个线程在执行, //主线程执行到run就执行完再出来,之前是d这个线程来执行demorun for(int x = 0;x<120;x++) { System.out.println("main在运行"); } } } class Demo extends Thread { public void run() { for(int x = 0;x<120;x++) { System.out.println("demo在运行"); } } }
步骤:
将线程要运行的代码存放在该run方法中。
为什么要将runnable接口的子类对象传递给thread的构造函数。
因为,自定义的run方法所属的对象是runnable接口的子类对象。
所以要让线程去指定指定对象的run方法。就必须明确该run方法所属对象
//第一种创建线程的方式 //1.继承Thread //2.复写public void run //3.new 一个类 然后这个 类.start() public class TicketSellDemo { public static void main(String[] args) { Ticket t1 = new Ticket(); Ticket t2 = new Ticket(); Ticket t3 = new Ticket(); Ticket t4 = new Ticket(); t1.start(); t2.start(); t3.start(); t4.start(); } } class Ticket extends Thread { //public int TicketNum = 100 ;//每个线程都卖100张票 public static int TicketNum = 100;//四个线程共卖100张 ,但是static 存储空间大,不建议用!!!!!!!!!!!!!!!! public void run() { while(true) { if(TicketNum>0) { System.out.println(Thread.currentThread().getName()+"......"+TicketNum--); } else { break; } //这就是效果,会出现共同卖一张票的结果,因为每个线程以创建 TicketNum都是100,所以会出现这样的问题 //Thread-1......100 //Thread-3......100 //Thread-0......100 //Thread-2......100 //Thread-0......99 //Thread-3......99 //Thread-1......99 //Thread-3......98 //Thread-0......98 } } }
/第二种创建线程方式 //1.定义类实现runnable接口 //2.覆盖runnable接口中的run方法。 //将线程要运行的代码存放在该run方法中。 //3.通过thread类建立线程对象。 //4.将runnable接口的子类对象作为实际参数传递给thread类的构造函数 //为什么要将runnable接口的子类对象传递给thread的构造函数。 //因为,自定义的run方法所属的对象是runnable接口的子类对象。 //所以要让线程去指定指定对象的run方法。就必须明确该run方法所属对象 //5.调用thread类的start方法开启线程并调用runnable接口子类的run方法 class TicketSellDemo { public static void main(String[] args) { Ticket t = new Ticket(); Thread t1 = new Thread(t); Thread t2 = new Thread(t); Thread t3 = new Thread(t); Thread t4 = new Thread(t); t1.start(); t2.start(); t3.start(); t4.start(); System.out.println("我是最后一个"); } } class Ticket implements Runnable { private int TicketNum = 100; public void run() { while(true) { if(TicketNum >0) { try { Thread.sleep(500); } catch (Exception e) { throw new RuntimeException("错误"); } System.out.println(Thread.currentThread().getName()+"....."+TicketNum--); } else { break; } } } } //效果 //Thread-1.....3 //Thread-0.....2 //Thread-1.....1 //Thread-3.....-1 //Thread-2.....0 //Thread-0.....-2
//通过分析,发现,打印出0,-1,-2等错票。
//多线程的运行出现了安全问题
//问题的原因:
//当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,
//另一个线程参与进来执行,导致共享数据的错误。
//解决方法:
//对多条操作共享数据的语句,只能让一个线程都执行完在执行过程中,其他线程不可以参与执行
下一章解决多线程安全问题
实现方式好处:避免了单继承的局限性。
在定义线程时,建立使用实现方式。
两种实现方式区别:
继承thread:线程代码存放thread子类run方法中。
实现runnable,线程代码存在接口的子类的run方法。
//现在来解决他 class TicketSellDemo { public static void main(String[] args) { Ticket t = new Ticket(); Thread t1 = new Thread(t); /* 这句话确实创建了一个线程 t1.start(); 也确实运行了一个线程 但是如果这样运行的话什么都没有,因为t1.start();跑的是thread的run方法,他的run方法中没有卖票,而Ticket t = new ticket();这个创建的对象有卖票的方法。 那么怎么把这两者联系起来呢? Thread (runnable target)//分配新的thread对象 于是写为Thread t1 = new thread(t); 这样就可正常了 而且用了接口方法,实现了多线程一起卖100张票。(static存储空间大) */ Thread t2 = new Thread(t); Thread t3 = new Thread(t); Thread t4 = new Thread(t); t1.start(); t2.start(); t3.start(); t4.start(); System.out.println("我是最后一个"); } } class Ticket implements Runnable { private int TicketNum = 100; //1.必须要有两个或者两个以上的线程。 //2.必须是多个线程使用同一个锁。就是那个Object obj = new Object(); Object obj = new Object(); public void run() { while(true) { synchronized(obj) { if(TicketNum>0) { try { Thread.sleep(30); } catch (Exception e) { } System.out.println(Thread.currentThread().getName()+"......"+TicketNum--); } } } } }
public class BankDemo { public static void main(String[] args) { Cust cu = new Cust(); Thread t1 = new Thread(cu); Thread t2 = new Thread(cu); t1.start(); t2.start(); } } class Bank { private int sum; Object obj = new Object(); public void add(int money) { synchronized(obj) { sum = sum +money; ///线程可能在这里挂起,然后出现问题 try { Thread.sleep(100); //必须要加这个,否则不会出问题 //打印3 // Thread-0----200 // Thread-1----200 // Thread-1----400 // Thread-0----500 // Thread-0----600 // Thread-1----600 } catch(Exception e) { } System.out.println(Thread.currentThread().getName()+"----"+sum); //正常打印 //Thread-0----100 //Thread-0----200 //Thread-0----300 //Thread-1----400 //Thread-1----500 //Thread-1----600 } //这个也是需要同步的!!!否则会出现上面的打印3 //System.out.println(Thread.currentThread().getName()+"----"+sum); /* 或者直接写成同步函数 同步分为:同步代码块,同步函数 Private int sum; //Object obj = new object(); Public Synchronized void add(int n) { Sum = sum+n; Try{thread.sleep(10);}catch(exception e){} ///线程可能在这里挂起,然后出现问题 System.out.println(“sum=”+sum); } */ } } class Cust implements Runnable { private Bank bk = new Bank(); public void run() { //正常效果 //Thread-1----200 //Thread-0----100 //Thread-1----300 //Thread-1----500 //Thread-0----400 //Thread-0----600 //Bank bk = new Bank();//如果放这里效果会这样!!! //Thread-1----100 //Thread-0----100 //Thread-1----200 //Thread-0----200 //Thread-1----300 //Thread-0----300 for(int i = 0; i<3;i++) { bk.add(100); } } }
public class ThisLockDemo { public static void main(String[] args) { Ticketl t =new Ticketl(); Thread t1 = new Thread(t); Thread t2 = new Thread(t); t1.start(); //为了让主线程在这停,这时能运行的只有t1,如果没有这段话,t1可能启动,但是没有获得执行权, //主线程一热按在执行,可能把下面两句话执行完了(t1.start();t.flag = false;),可能就执行一个 //主线程执行完毕,t1获得执行权,再执行恐怕t1t2都在同步函数中执行,flag没起到应有作用 try { Thread.sleep(2); } catch (Exception e) { throw new RuntimeException("cuowu"); } System.out.println("dier"); t.flag = false; t2.start(); } } class Ticketl implements Runnable { private int num = 100; boolean flag = true ; Object obj = new Object(); public void run() { if(flag) { while(true) { //同步代码块 //假设这里是A线程 //为了配合静态同步函数,锁也可以写 类名.class synchronized(this)//如果是obj那么打印会有0票,因为跟同步函数不是一个锁,用this才是同一个锁 //打印Thread-0--2---0 { if(num>0) { try//这里一定要加sleep//要不然看不出效果 { Thread.sleep(100); } catch (Exception e) { } System.out.println(Thread.currentThread().getName()+"--2---"+num--); } else { break; } } } } else { while(true) { if(num>0) { show(); } else { break; } } } } //假设这里是B线程
<span style="white-space:pre"> </span>//public static <span style="font-family: Arial, Helvetica, sans-serif;">synchronized void show() 可以用来判断静态用的是什么锁</span> public synchronized void show() //同步函数用的是this,因为函数是被对象调用的 { try { Thread.sleep(10); //如果不同线程所不同,那么num =1 进入B线程,拿到B的锁,在这sleep,释放执行权 //但是不释放锁, //然后A获得执行权,因为锁不一样,所以可以继续跑他的代码,打印num = 1 //然后B获得执行权,又打印num = 0 //如果AB锁相同,那么B在这里sleep的时候,没有释放锁,A拿不到锁,也执行不了代码 //!!!!! } catch (Exception e) { } System.out.println(Thread.currentThread()+"--1---"+num--); } }
class Single { private static final Single s = new Single();//写final更为严谨 private Single(){} public static Single getInstance() { return s; } }
class Single { private static Single s = null; private Single(){} /* //public static synchronized Single getInstance()//每次判断锁比较低效 { if(s == null ) { //可能在这里挂起,如果A在这挂起,B也挂这,A醒了new一个,B醒了又new了一个 //单例模式就是只要一个对象,所以这里不行 s = new Single(); } } */ public static Single getInstance() { if(s == null) { synchronized(Single.class) { if(s == null ) { //可能在这里挂起,如果A在这挂起,B也挂这,A醒了new一个,B醒了又new了一个 //单例模式就是只要一个对象,所以这里不行 s = new Single(); //这里只要一个初始化完成后面的就不需要判断锁 } } } return s; } } class SingleDemo { public static void main(String[] args) { System.out.println("Hello World"); } }
public class DeadLockDemo { public static void main(String[] args) { Thread t1 = new Thread(new Test1(true)); Thread t2 = new Thread(new Test1(false)); t1.start(); t2.start(); } } class Test1 implements Runnable { private boolean flag; Test1(boolean flag) { this.flag = flag; } public void run() { if(flag) { synchronized(MyLock.locka) { //如果判断不是loca就会等在这里//进来就拿了locka,在这等lockb System.out.println("if locka"); synchronized(MyLock.lockb) { System.out.println("if lockb"); } System.out.println("out1"); } } else { synchronized(MyLock.lockb) { //如果判断不是locb就会等在这里//进来就拿了lockb,在这等locka System.out.println("else lockb"); synchronized(MyLock.locka) { System.out.println("else locka"); } System.out.println("out2"); } } } } class MyLock { static Object locka = new Object(); static Object lockb = new Object(); }
</pre><pre name="code" class="java">class Res { String name; String sex; } class Input implements Runnable { private Res r; //Object obj = new Object(); //代码1 用了1处的代码同步依然会出现问题,因为不满足两个前提的第二个,不是同一个锁 //因为这里的Object obj = new object();跟输出的Object obj = new object();, //指的不是同一个,因此两个的锁不一样。 Input(Res r) { this.r =r; } public void run() { int x = 0; while(true) { //synchronized(obj) //代码1 synchronized(r) //代码2 { if(x==0) { r.name = "mike"; //易出现问题 //如果在这里刚给完名字,就被输出线程抢走执行权,那么就打印mike 女女女 r.sex = "man"; } else { r.name = "丽丽"; //易出现问题 //如果在这里刚给完名字,就被输出线程抢走执行权,那么就打印丽丽 nan r.sex = "女女女女"; } x =(x+1)%2; } } } } class Output implements Runnable { private Res r ; //Object obj = new Object(); //代码1 Output(Res r) { this.r =r; } public void run () { while(true) { //synchronized(obj)//代码1 synchronized(r) //代码2//或者可以写input.class,output.class,只要唯一的都可以写,但是比较牵强 { System.out.println(r.name+"...."+r.sex); } } } } class InputOutDemo { public static void main(String[] args) { Res r = new Res(); Input in = new Input(r); Output out = new Output(r); Thread t1 = new Thread(in); Thread t2 = new Thread(out); t1.start(); t2.start(); } } */ //打印效果 //mike....man //mike....女女女女 //丽丽....女女女女 //丽丽....man //丽丽....man //所以添加代码1,但是两个obj不是一样的 ,锁不一样,可以都写input.class,output.class,但是比较牵强,所以用r //添加代码2 //但是有一个问题,如果输入线程写完名字,被输出抢掉执行权,那么有可能会被不断打印,不能实现输一打一,所以更新代码如下
class Res { String name; String sex; boolean flag = false; } class Input implements Runnable { private Res r; Input(Res r) { this.r =r; } public void run() { int x = 0; while(true) { synchronized(r) { if(r.flag) { try { r.wait(); //等待线程都存线程池中,r.wait()是指让r这个锁的线程等待,其他线程无关 } catch (Exception e) { } } if(x==0) { r.name = "mike"; r.sex = "man"; } else { r.name = "丽丽"; r.sex = "女女女女"; } x =(x+1)%2; r.flag = true; //写完一次数据,准备让输出打印一次 r.notify(); //叫醒线程,唤醒的是线程池中的线程,唤醒第一个等待的,只能唤醒一个!!! //r.notify()是指r这个锁的线程唤醒 , } //类似于两伙小朋友(相当于两个锁的线程),这一伙的小朋友定住了,只能这一伙的小朋友解定 } } } class Output implements Runnable { private Res r ; Output(Res r) { this.r =r; } public void run () { while(true) { synchronized(r) { if(!r.flag) { try { r.wait(); //wait不能抛,因为外面没抛出异常!!! //因为在使用wait()的时候会抛出异常所以必须使用try,同时也要用r.wait // 因为wait在其他线程调用此对象notify()或notifyall()方法前,导致当前线程等待。 // 换句话说,此方法的行为就好像他仅执行wait(0)调用一样。 // 当前线程必须拥有此对象的监视器。该线程发布对此监视器的所有权并等待, // 直到其他线程通过调用notify方法,或notifyall方法通知再次对象的监视器上等待的线程醒来。 // 然后该线程将等到重新获得对监视器的所有权后才能继续执行。 // } catch (Exception e) { } } System.out.println(r.name+"...."+r.sex); r.flag = false; //数据打印完一次,等待输入 r.notify();//唤醒线程(只能唤醒一个) } } } } class InputOutDemo { public static void main(String[] args) { Res r = new Res(); Input in = new Input(r); Output out = new Output(r); Thread t1 = new Thread(in); Thread t2 = new Thread(out); t1.start(); t2.start(); } }
class Res { private String name; private String sex; private boolean flag = false; public synchronized void set(String name, String sex) { if(this.flag)//可以不写flag //因为都是r调用,所以输入输出使用的锁都一样 { try { this.wait(); //等待线程都存线程池中,r.wait()是指让r这个锁的线程等待,其他线程无关 } catch (Exception e) { } } this.name = name; this.sex = sex; flag =true; this.notify(); } public synchronized void out() { if(this.flag)//可以不写flag//可以不写flag //因为都是r调用,所以输入输出使用的锁都一样 { try { this.wait(); //等待线程都存线程池中,r.wait()是指让r这个锁的线程等待,其他线程无关 } catch (Exception e) { } } System.out.println(name+"....."+sex); flag =false; this.notify(); } } class Input implements Runnable { private Res r; Input(Res r) { this.r =r; } public void run() { int x = 0; while(true) { if(x==0) { r.set("mike", "man"); } else { r.set("丽丽", "女女女女"); } x =(x+1)%2; } } } class Output implements Runnable { private Res r ; Output(Res r) { this.r =r; } public void run () { while(true) { r.out(); } } } class InputOutDemo { public static void main(String[] args) { Res r = new Res(); //Input in = new Input(r); //Output out = new Output(r); //Thread t1 = new Thread(in); //Thread t2 = new Thread(out); //t1.start(); //t2.start(); new Thread(new Input(r)).start(); new Thread(new Output(r)).start(); } }
class Res { String name; String sex; Boolean flag =false; // private String name; // private String sex; // private Boolean flag =false; // public synchronized void set(String name,String sex) // { // if(flag) // try{this.wait();} // catch(exception e){} // this.name = name; //因为可能赋值的时候卡在这 // this.sex = sex; // flag = true; // this.notify(); // } // public synchronized void out() // { // if(!flag) // try{this.Wait();} // catch(exception e){} // System.out.println(name+"....."+sex); // flag = false; // this.notify(); // } } class Input implements Runnable { private Res r; //Object obj = new object();// 1 用了1处的代码同步依然会出现问题,因为不满足两个前提的第二个,不是同一个锁 //因为这里的Object obj = new object();跟输出的Object obj = new object();, //指的不是同一个,因此两个的锁不一样。 Input(Res r) { this.r =r; } public void run() { int x = 0; while(true) { //{ //if(r.flag)//有这个颜色用的是等待唤醒机制。 //try{r.Wait();} //catch(exception e){} // 因为在使用wait()的时候会抛出异常所以必须使用try,同时也要用r.wait // 因为wait在其他线程调用此对象notify()或notifyall()方法前,导致当前线程等待。 // 换句话说,此方法的行为就好像他仅执行wait(0)调用一样。 // 当前线程必须拥有此对象的监视器。该线程发布对此监视器的所有权并等待, // 知道其他线程通过调用notify方法,或notifyall方法通知再次对象的监视器上等待的线程醒来。 // 然后该线程将等到重新获得对监视器的所有权后才能继续执行。 // //synchronized(obj) //1 //用代码 2 就OK了,因为R都是同样的对象, // 所以所也一样,或者可以写input.class,output.class,只要唯一的都可以写, // 但是现在打印会出现输入很多次然后打印很多次,最好实现输一次, // 打印一次,3 代码,解决这个问题 synchronized(r) //2 { if(r.flag)//3 有这个颜色用的是等待唤醒机制。 try{r.wait();} //3 为什么不能抛???????? catch(Exception e){} //3 if(x==0) { r.name = "mike"; //易出现问题 r.sex = "man"; } else { r.name="丽丽"; //易出现问题 r.sex="女女女"; } x=(x+1)%2; r.flag =true; //3 r.notify();//3 因为在res中写了公共接口函数 } //r.flag =true; //r.Notify();//因为在res中写了公共接口函数 //所以可以用下面的代替 //if(x==0) //R.set("mike","man"); //Else //R.set("丽丽","女女女女"); //X=(x+1)%2; } } } class Output implements Runnable { private Res r; //Object obj = new object(); //1 Output(Res r) { this.r=r;//this.r是private res r; } public void run() { while(true) { //Synchronized(obj) //Synchronized(r) //{ //if(!r.flag)//如果线程notify之后,没到这个wait(),执行权就被抢走了,那么也没事,过程还是一样的(可以看看代码) //try{r.Wait();}catch(exception e){} //放弃执行权 //System.out.println(r.name+"...."+r.sex); //r.flag =flase; //r.Notify();//通知别的线程活了 //}res写了公共函数,所以可以用下面的代替 //synchronized(obj) //1 synchronized(r) //2 { //如果线程notify之后,没到这个wait(), //执行权就被抢走了,那么也没事,过程还是一样的(可以看看代码) if(!r.flag) //3 try{r.wait();}catch(Exception e){} //3 //放弃执行权 System.out.println(r.name+"...."+r.sex); r.flag =false; //3 r.notify();//3 //两拨小朋友 一拨的只能唤醒自己的一拨 } //r.out(); } } } class InputOutputDemo { public static void main(String[] args) { Res r = new Res(); //new Thread(new input(r)).start(); //new Thread(new output(r)).start(); Input in =new Input(r); Output out =new Output(r); Thread t1 = new Thread (in); Thread t2 = new Thread (out); t1.start(); t2.start(); } }
public class ProducerCustomer { public static void main(String[] args) { Resource r = new Resource(); //new Thread(new Pro(r)).start(); //new Thread(new Custo(r)).start(); //两个线程看不出为什么下面非要用while Thread t1 = new Thread(new Pro(r)); Thread t2 = new Thread(new Pro(r)); Thread t3 = new Thread(new Custo(r)); Thread t4 = new Thread(new Custo(r)); t1.start(); t2.start(); t3.start(); t4.start(); //打印1 //有时候会消费两次,生产一次,有时候也会消费次生产两次 //消费者:商品--count--114292 //消费者:商品--count--114292 //生产者:商品--count--114293 //消费者:商品--count--114293 //消费者:商品--count--114293 //生产者:商品--count--114294 //消费者:商品--count--114294 //消费者:商品--count--114294 } } class Resource { private Resource r; private String name; private int count =1; private boolean flag = false; //分析下为什么出现打印1问题 // 生产者 t1 t2 // 消费者 t3 t4 线程池 // t1开始进入生产一个,然后notify,因为t1wait(释放锁,释放执行权) 1 2 3 // 假设,这时候被t2抢到执行权,因为flag = true,所以t2wait(释放锁,释放执行权) <span style="white-space:pre"> </span>t1 t2 // 只是t3抢到执行权 ,生产一个,然后notify, 线程池t1被唤醒(因为他是第一个放进去的) <span style="white-space:pre"> </span>t2 // t3不一定释放执行权,加入他没释放,继续执行然后wait了(释放锁,释放执行权) <span style="white-space:pre"> </span>t2 t3 //假设现在执行权被t4抢到,他也会wait t2 t3 t4 //这时候只能t1活动,于是生产一次,notify一次,于是t2被唤醒,但是不一定获得执行权 t3 t4 //假设t1继续执行,wait,这时候只能t2出来 t3 t4 t1 //t2之前是在wait的地方,如果开始执行就继续往下走,又生产一次(因为用的是if,之判断一次),所以问题出现了,生产了两次,消费一次 //那么我们用while(),醒来之后可以继续判断,t2被唤醒之后,while()条件不符合, //只能继续再循环里面wait t3 t4 t1 t2 <span style="white-space:pre"> </span> //完了这回全都wait了,所以用while就必须要用notifyall(),全部唤醒 public synchronized void set(String name) { if(flag)//需要写成while(!flag)为了让每次在wait等待的线程被唤醒之后判断一下while(),但是配合notifyallc才行 //如果用if的话,会直接往下走,不判断if(); { try { this.wait(); } catch (Exception e) { } } this.name = name+"--count--"+count++; System.out.println("生产者:"+this.name); flag = true;//生产了一个 this.notify(); //唤醒用this锁的线程 } public synchronized void out() { if(!flag)//需要写成while(!flag)为了让每次在wait等待的线程被唤醒之后判断一下while(),但是配合notifyallc才行 //如果用if的话,会直接往下走,不判断if(); { try { this.wait(); } catch (Exception e) { } } System.out.println("消费者:"+this.name); flag = false;//生产了一个 this.notify(); //唤醒用this锁的线程 } } class Pro implements Runnable { private Resource r; Pro(Resource r) { this.r =r; } public void run() { while(true) { r.set("商品"); } } } class Custo implements Runnable { private Resource r; Custo(Resource r) { this.r =r; } public void run() { while(true) { r.out(); } } }
public class ProducerCustomer { public static void main(String[] args) { Resource r = new Resource(); Thread t1 = new Thread(new Pro(r)); Thread t2 = new Thread(new Pro(r)); Thread t3 = new Thread(new Custo(r)); Thread t4 = new Thread(new Custo(r)); t1.start(); t2.start(); t3.start(); t4.start(); } } class Resource { private Resource r; private String name; private int count =1; private boolean flag = false; private Lock lock = new ReentrantLock(); //Condition 实例实质上被绑定到一个锁上。要为特定 Lock 实例获得 Condition 实例,请使用其 newCondition() 方法。 //Condition为每个对象提供多个等待,多个唤醒!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! private Condition condition_pro = lock.newCondition(); //生产者的wait 唤醒 private Condition condition_con = lock.newCondition(); //消费者的wait 唤醒 public void set(String name)//throws Exception { lock.lock(); //进来就锁 try { while(flag) { condition_pro.await(); } this.name = name+"--count--"+count++; System.out.println(Thread.currentThread().getName()+"生产者:"+this.name); flag = true;//生产了一个 condition_con.signal(); //唤醒用this锁的线程 } catch(Exception e) { } finally { lock.unlock();//释放锁的动作一定要执行 } } public void out() //throws Exception { lock.lock(); { try { while(!flag) condition_con.await(); System.out.println(Thread.currentThread().getName()+"消费者:"+this.name); flag = false;//生产了一个 condition_pro.signal(); //唤醒用this锁的线程 } catch (Exception e) { // TODO: handle exception } finally { lock.unlock();//释放锁的动作一定要执行 } } } } class Pro implements Runnable { private Resource r; Pro(Resource r) { this.r =r; } public void run() { while(true) { try { r.set("商品"); } catch (Exception e) { } } } } class Custo implements Runnable { private Resource r; Custo(Resource r) { this.r =r; } public void run() { while(true) { try { r.out(); } catch (Exception e) { } } } }
class Stop implements Runnable { private boolean flag = true; public void run() { while(flag) { System.out.println(Thread.currentThread().getName()+"...run"); } } public void changeflag() { flag =false; } } class StopThreadDemo { public static void main(String[] args) { Stop st =new Stop(); Thread t1 = new Thread(st); Thread t2 = new Thread(st); t1.start(); t2.start(); int num=0; while(true) { if(num++== 60) { st.changeflag(); break; } System.out.println(Thread.currentThread().getName()+"...."+num); } } }
class Stop implements Runnable { private boolean flag = true; public synchronized void run() { while(flag) { try { //线程0进来在这wait了,线程1进来也在这wait了(wait释放锁释放执行权,所以线程1就进来了) wait(); //因为得先醒来执行完下面的东西,在执行while()才能结束 } catch(InterruptedException e)//发生中断跳到这 { System.out.println(Thread.currentThread().getName()+"...run"); flag = false; } System.out.println(Thread.currentThread().getName()+"...run"); } } public void changeflag() { flag =false; } } class StopThread { public static void main(String[] args) { Stop st =new Stop(); Thread t1 =new Thread(st); Thread t2 =new Thread(st); t1.start(); t2.start(); int num=0; while(true) { if(num++ == 60) { //St.changeflag(); t1.interrupt();//唤醒冻结状态(线程挂起) //是线程产生中断!!!!!!!!!!!!!!!!! t2.interrupt(); break; } System.out.println(Thread.currentThread().getName()+"...."+num); } System.out.println("over"); } }
class Stop1 implements Runnable { private boolean flag = true; public synchronized void run() { while(true) { System.out.println(Thread.currentThread().getName()+"...run"); } } public void changeflag() { flag =false; } } class ProtectThread { public static void main(String[] args) { Stop1 st =new Stop1(); Thread t1 =new Thread(st); Thread t2 =new Thread(st); t1.setDaemon(true); t2.setDaemon(true); t1.start(); t2.start(); int num=0; while(true) { if(num++ == 60) { //St.changeflag(); t1.interrupt();//唤醒冻结状态(线程挂起) t2.interrupt(); break; } System.out.println(Thread.currentThread().getName()+"...."+num); } System.out.println("over"); } }
class demo implements Runnable { public void run() { For(int x=0;x<70;x++) { System.out.println(thread.currentthread().getname()+”.....”+x); } } } class joindemo { <span style="white-space:pre"> </span>Public static void main(String[] args) throws Exception <span style="white-space:pre"> </span>{ <span style="white-space:pre"> </span>Demo d = new demo(); <span style="white-space:pre"> </span>thread t1 = new thread(d); <span style="white-space:pre"> </span>thread t2 = new thread(d); <span style="white-space:pre"> </span>t1.start(); <span style="white-space:pre"> </span>t1.join();//要CPU执行权,t1结束了,主线程才会活过来,碰到谁的join,就等谁挂了才活过来 <span style="white-space:pre"> </span>t2.start();
<span style="white-space:pre"> </span>for(int x=0;x<80;x++) <span style="white-space:pre"> </span>{ <span style="white-space:pre"> </span>System.out.println(“main....”+x); <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>System.out.println(“over”); <span style="white-space:pre"> </span>} }
/* 用两种创建线程方法代码 */ class Threadtest { public static void main(String[] args) { new Thread() { public void run() { for(int x=0;x<100;x++) { System.out.println(Thread.currentThread().getName()+"...."+x); } } }.start(); for(int x=0;x<100;x++) { System.out.println(Thread.currentThread().getName()+"...."+x); } Runnable r = new Runnable() { public void run() { for(int x=0;x<100;x++) { System.out.println(Thread.currentThread().getName()+"...."+x); } } }; new Thread(r).start(); } } /* Runnable rn = new Runnable() { public void run() { } }; 这两个是一样的 class Anomymous implements Runnable { public void run() { } } Runnable rn = new Anomymous(); */
class Demo2 implements Runnable { public void run() { for(int x=0;x<70;x++) { System.out.println(Thread.currentThread().getName()+"....."+x); //Thread.yield();//释放执行权,你一下我一下 } } } class PriorityYieldDemo { public static void main(String[] args) throws Exception { Demo2 d = new Demo2(); Thread t1 = new Thread(d); Thread t2 = new Thread(d); t1.start(); t1.setPriority(Thread.MAX_PRIORITY);//数据固定定位常量,数据共享定位静态 t1.join();//要CPU执行权,t1结束了,主线程才会活过来,碰到谁的join,就等谁挂了才活过来 t2.start(); for(int x=0;x<80;x++) { System.out.println("main...."+x); } System.out.println("over"); } }