标签:
一个线程是进程内的一个单一的顺序控制流程图,多线程是指一个进程可以同时运行几个任务,每个任务由一个线程来完成。即多个线程可以同时运行,并且在一个进程内执行不同的任务。
1.创建线程两种方法方法一,
继承自Thread:
(1).定义一个类继承Thread类(2).覆盖Thread中的run()方法(3).直接创建Thread类的对象并测试线程。(4).调用线程的start方法,开启线程并调用线程的run方法并执行。
class Demo extends Thread{ String name; Demo(String name){ super(name); //this.name=name; } @Override public void run() { for(int i=0;i<10;i++){ System.out.println(name+"................."+i+"......name="+Thread.currentThread().getName()); } } } public class ThreadDemo { public static void main(String[] args) { //三个线程,主线程和其他俩个线程 Demo d1=new Demo("xia"); Demo d2=new Demo("里面"); d1.start(); d2.start(); System.out.println("over======="+Thread.currentThread().getName()); } }
(程序结束,但是线程不一定结束。)
2.实现Runnable接口--------->将线程对象的任务从线程的子类中分离出来,进行单独的封装,按照面向对象的思想将任务封装成对象,避免的java的单继承。
(1).定义类实现Runnable接口(2).覆盖接口中的run方法,将线程的任务代码封装到run方法中(3).通过Thread类创建线程对象,并将Runnable接口的子类对象作为Thread类的构造函数的参数进行传递(4).调用线程对象的start方法开启线程
class Ticket implements Runnable { private int num = 100; int j=0; public void run() { while (true) { synchronized (this) { if (num > 0){ j++; //Thread.currentThread().getName()是获取当前线程的名字,Thread-编号,其中编号是从0开始的。 System.out.println(j+"==="+Thread.currentThread().getName() + "-----------" + num--); } else break; } } } } public class ThreadDemo1 { 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(); } }
run()方法:run方法中定义的就是线程要运行的任务代码,开启线程是为了运行指定代码,所有只有继承了Thread类,复写run方法,将运行的代码定义到run方法中进行
2.线程的同步问题
线程的安全产生的原因:多个线程在操作共享的数据,或,操作共享数据的线程代码有多条
当线程在执行共享操作共享数据的多条代码,其他线程参与运算就会导致线程安全问题的产生。
线程同步的处理方式:
创建同步方法:
package my1.exa.dao; class Bank{ private int sum; synchronized void add(int money){ sum=sum+money; System.out.println(sum); } } class Costum implements Runnable{ Bank b=new Bank(); @Override public void run() { for(int i=0;i<3;i++){ b.add(100); } } } public class SyncThreadDemo { public static void main(String[] args) { Costum co=new Costum(); Thread th1=new Thread(co); Thread th2=new Thread(co); th1.start(); th2.start(); } }
创建同步代码块:
class Ticket1 implements Runnable { private static int num = 100; Object ob=new Object(); public void run() { while (true) { synchronized (ob) { if (num > 0){ System.out.println(Thread.currentThread().getName() + "------obj-----" + num--); } } } } } public class SynFuncationLockDemo { public static void main(String[] args) throws InterruptedException { Ticket1 tm = new Ticket1(); Thread t1=new Thread(tm); Thread t2=new Thread(tm); t1.start(); t2.start(); } }
同步函数中使用的锁是this 同步函数和同步代码块的区别是:同步函数的锁是固定的this,同步代码块中的锁是任意的对象
静态同步函数中使用的同步锁是该函数所属的字节码文件对象,用getClass方法获取,或者用当前类名.class获取。
标签:
原文地址:http://www.cnblogs.com/nolonely/p/5928011.html