创建多线程的两种方法:
1. 继承Thread类并重写Thread类中的run()方法。
class Test extends Thread{ @Override public void run(){ //所要执行多线程的代码 } }
2.实现Runnable接口,实现其run()方法。
class Test implements Runnable{ @Override public void run(){ //所要执行多线程的代码 } }
多线程中所存在的线程安全问题:
由于没有锁的加持,多个线程同时操作共享数据,所以获得的共享数据很有可能是脏数据(窗口售票出现重票,错票的现象,这就是所谓的脏数据)。
package ThreadDemo; /** * 测试类 */ public class Test1 { public static void main(String[] args) { Window w = new Window(); Thread t1 = new Thread(w); Thread t2 = new Thread(w); t1.setName("窗口1"); t2.setName("窗口2"); t1.start(); t2.start(); } } /** * 售票窗口 */ class Window implements Runnable{ int tickets = 100; @Override public void run(){ while(tickets > 0){ if(tickets > 0){ try { Thread.currentThread().sleep(10); //增加sleep()方法增加出现线程安全的几率 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " 正在售出: " + tickets-- + "号票"); }else{ break; } } } }
如何解决线程安全问题:
(synchronized)关键字非常重要
我们把线程之间的工作方式想象成多个人去wc,当只有一个厕所时,一个人进入时会将厕所锁上,并且厕所门上会显示block。这就是锁,当这个人上完厕所时,打开门,将block变为open。其他人才有机会上厕所。
1.同步代码块:
synchronized(Object obj){ 操作共享数据的代码 }
//使用实现接口方法创建线程的可以传入this,使用继承Thread类创建线程的方法最好不要用this。确保对象为公有的。
package ThreadDemo; /** * 测试类 */ public class Test1 { public static void main(String[] args) { Window w = new Window(); Thread t1 = new Thread(w); Thread t2 = new Thread(w); t1.setName("窗口1"); t2.setName("窗口2"); t1.start(); t2.start(); } } /** * 售票窗口 */ class Window implements Runnable{ int tickets = 100; @Override public void run(){ while(tickets > 0){ synchronized(this){ if(tickets > 0){ try { Thread.currentThread().sleep(10); //增加sleep()方法增加出现线程安全的几率 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " 正在售出: " + tickets-- + "号票"); }else{ break; } } } } }
2.同步方法:
public synchronized void XX(){操作共享数据的代码} //this
原文:https://www.cnblogs.com/weiss/p/11135629.html