/*
栗子 通过Runnable接口实现简历线程实例
*/
class Dog implements Runnable{
//重写run函数
public void run(){
int times = 0 ;
while(true){
try{
Thread.sleep(1000);
}catch (Exception e){
e.printStackTrace();
}
times++;
System.out.println("hello ,thread_world! " + times);
if(times==10){
break;
}
}
}
}
public class Test_Thread {
public static void main(String[] args){
Dog dog = new Dog();
Thread t = new Thread(dog);
t.start();
}
}
【结果】
"C:\Program Files\Java\jdk1.7.0_67\bin\java" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2017.2.3\lib\idea_rt.jar=6342:C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2017.2.3\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.7.0_67\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.7.0_67\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.7.0_67\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.7.0_67\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.7.0_67\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.7.0_67\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.7.0_67\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.7.0_67\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.7.0_67\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.7.0_67\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.7.0_67\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.7.0_67\jre\lib\jce.jar;C:\Program Files\Java\jdk1.7.0_67\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.7.0_67\jre\lib\jfxrt.jar;C:\Program Files\Java\jdk1.7.0_67\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.7.0_67\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.7.0_67\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.7.0_67\jre\lib\resources.jar;C:\Program Files\Java\jdk1.7.0_67\jre\lib\rt.jar;D:\zidonghua\java_test_one\target\test-classes" Test_Thread
hello ,thread_world! 1
hello ,thread_world! 2
hello ,thread_world! 3
hello ,thread_world! 4
hello ,thread_world! 5
hello ,thread_world! 6
hello ,thread_world! 7
hello ,thread_world! 8
hello ,thread_world! 9
hello ,thread_world! 10
Process finished with exit code 0
/*
栗子 多线程实例
1. 一个线程通过接受n来执行1+..+n
2. 另一个线程每隔1秒输出一次hello world!
*/
class Pig implements Runnable{
int n = 0;
int times = 0;
public Pig(int n){
this.n = n;
}
public void run(){
while(true){
try{
Thread.sleep(1000);
}catch (Exception e){
e.printStackTrace();
}
times++;
System.out.println("我是一个线程,正在输出第" + times + "个hello world!");
if(times == this.n){
break;
}
}
}
}
//算术题
class Bird implements Runnable{
int n = 0;
int res = 0;
int times = 0;
public Bird(int n){
this.n = n;
}
public void run(){
while(true){
try{
Thread.sleep(1000);
}catch (Exception e){
e.printStackTrace();
}
res += (++times);
System.out.println("当前结果是:"+ res);
if(times == this.n){
System.out.println("最后结果是:" + res);
break;
}
}
}
}
public class Test_Thread {
public static void main(String[] args){
Pig pig = new Pig(5);
Bird bird = new Bird(5);
Thread t1 = new Thread(pig);
Thread t2 = new Thread(bird);
t1.start();
t2.start();
}
}
【结果】
我是一个线程,正在输出第1个hello world!
当前结果是:1
我是一个线程,正在输出第2个hello world!
当前结果是:3
我是一个线程,正在输出第3个hello world!
当前结果是:6
我是一个线程,正在输出第4个hello world!
当前结果是:10
我是一个线程,正在输出第5个hello world!
当前结果是:15
最后结果是:15
/*
栗子 深入理解 线程对象只能启动一个线程 不论继承Thread或实现Runnable接口都不能使用start启动同一个线程2次
*/
class Cat extends Thread{
public void run(){
System.out.println("11");
}
}
class Dog implements Runnable{
public void run(){
System.out.println("2");
}
}
public class Test_Thread {
public static void main(String[] args){
Cat cat1 = new Cat();
cat1.start();
Dog dog1 = new Dog();
Thread t = new Thread(dog1);
t.start();
t.start();
}
}
【结果】
Exception in thread "main" 11
2
java.lang.IllegalThreadStateException
at java.lang.Thread.start(Thread.java:705)
at Test_Thread.main(Test_Thread.java:26)
两种创建线程的⽅法的区别
创建线程有两种⽅法: 1、继承Thread; 2、实现Runnable接⼝; 这两种⽅法有什么区别?
⽤实现Runnable接⼝的特点
1、⽤实现Runnable接⼝的⽅法创建对象可以避免java单继承机制带来的局限;
2、⽤实现Runnable接⼝的⽅法,可以实现多个线程共享同⼀段代码(数据);
因此建议⼤家如果你的程序有同步逻辑需求,则使⽤Runnable的⽅法来创建线程。
java线程的同步--提出问题
多线程的并发,给我们编程带来很多好处,完成更多更有效率的程序。但是也给我们带来
线程安全问题。
java线程的同步--解决问题
解决问题的关键就是要保证容易出问题的代码的原⼦性, 所谓原⼦性就是指:当a线程在
执⾏某段代码的时候,别的线程必须等到a线程执⾏完后,它才能执⾏这段代码。 也就是
排队⼀个⼀个解决。
java处理线程两步的⽅法⾮常简单,只需要在需要同步的代码段,⽤:
synchronized(Object){你要同步的代码}
java线程的同步--解决问题
对同步机制的解释:
java任意类型的对象都有⼀个标志位,该标志位具有0、 1两种状态,其开始状态为1,
当某个线程执⾏了synchronized(Object)语句后, object对象的标志位变为0的状态,直到
执⾏完整个synchronized语句中的代码块后,该对象的标志位⼜回到1状态。
当⼀个线程执⾏到synchronized(Object)语句的时候,先检查Object对象的标志位,如
果为0状态,表明已经有另外的线程正在执⾏synchronized包括的代码,那么这个线程将暂
时阻塞,让出CPU资源,直到另外的线程执⾏完相关的同步代码,并将Object对象的标志
位变为状态,这个线程的阻塞就被取消,线程能继续运⾏,该线程⼜将Object的标志位变
为0状态,防⽌其它的线程再进⼊相关的同步代码块中。
如果有多个线程因等待同⼀个对象的标志位⾯⽽处于阻塞状态时,当该对象的标志位恢
复到1状态时,只会有⼀个线程能够进⼊同步代码执⾏,其它的线程仍处于阻塞的状态。
特别说明:
1、上⾯所说的标志位⽤术语讲就是对象锁,⽂件锁。数据库会有⾏锁、表锁等
2、 synchronized(object)//object(就是对象锁)可以是任意类型对象